mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
chore: next merge feature
This commit is contained in:
commit
25e001f8b5
@ -15,6 +15,13 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 4.22.6
|
||||
|
||||
`2022-08-17`
|
||||
|
||||
- 🐞 Revert [#36710](https://github.com/ant-design/ant-design/pull/36710) to fix Table `onChange` argument `sorter` error in multiple columns sort.
|
||||
- 🐞 Fix Drawer can not close when config `opacity` on the `maskStyle`. [#37100](https://github.com/ant-design/ant-design/pull/37100)
|
||||
|
||||
## 4.22.5
|
||||
|
||||
`2022-08-15`
|
||||
|
@ -15,6 +15,13 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 4.22.6
|
||||
|
||||
`2022-08-17`
|
||||
|
||||
- 🐞 回滚 [#36710](https://github.com/ant-design/ant-design/pull/36710) 以修复 Table 多列排序时 `onChange` 中 `sorter` 参数错误的问题。
|
||||
- 🐞 修复 Drawer 的 `maskStyle` 配置 `opacity` 样式时无法关闭的问题。[#37100](https://github.com/ant-design/ant-design/pull/37100)
|
||||
|
||||
## 4.22.5
|
||||
|
||||
`2022-08-15`
|
||||
|
@ -457,9 +457,14 @@ describe('ConfigProvider', () => {
|
||||
testPair('Slider', props => {
|
||||
const myProps = { ...props };
|
||||
if (myProps.prefixCls) {
|
||||
myProps.tooltipPrefixCls = `${myProps.prefixCls}-tooltip`;
|
||||
return (
|
||||
<Slider
|
||||
tooltip={{ open: true, prefixCls: `${myProps.prefixCls}-tooltip` }}
|
||||
{...myProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <Slider tooltipVisible {...myProps} />;
|
||||
return <Slider tooltip={{ open: true }} {...myProps} />;
|
||||
});
|
||||
|
||||
// Spin
|
||||
|
@ -15,7 +15,7 @@ exports[`Drawer className is test_drawer 1`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -91,7 +91,7 @@ exports[`Drawer closable is false 1`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -139,7 +139,7 @@ exports[`Drawer getContainer return undefined 2`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 400px;"
|
||||
>
|
||||
<div
|
||||
@ -216,7 +216,7 @@ exports[`Drawer have a footer 1`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -297,7 +297,7 @@ exports[`Drawer have a title 1`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -378,7 +378,7 @@ exports[`Drawer render correctly 1`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 400px;"
|
||||
>
|
||||
<div
|
||||
@ -454,7 +454,7 @@ exports[`Drawer render top drawer 1`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-top-appear ant-drawer-panel-motion-top-appear-active ant-drawer-panel-motion-top"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="height: 400px;"
|
||||
>
|
||||
<div
|
||||
@ -533,7 +533,7 @@ exports[`Drawer style/drawerStyle/headerStyle/bodyStyle should work 1`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -612,7 +612,7 @@ exports[`Drawer support closeIcon 1`] = `
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 400px;"
|
||||
>
|
||||
<div
|
||||
|
@ -15,7 +15,7 @@ HTMLCollection [
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -24,7 +24,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -117,7 +117,7 @@ exports[`renders ./components/drawer/demo/config-provider.md extend context corr
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -126,7 +126,7 @@ exports[`renders ./components/drawer/demo/config-provider.md extend context corr
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -310,7 +310,7 @@ HTMLCollection [
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -319,7 +319,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 500px;"
|
||||
>
|
||||
<div
|
||||
@ -467,7 +467,7 @@ HTMLCollection [
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -476,7 +476,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 720px;"
|
||||
>
|
||||
<div
|
||||
@ -2512,7 +2512,7 @@ HTMLCollection [
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -2521,7 +2521,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 520px; transform: translateX(-180px);"
|
||||
>
|
||||
<div
|
||||
@ -2561,7 +2561,7 @@ HTMLCollection [
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -2570,7 +2570,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 320px;"
|
||||
>
|
||||
<div
|
||||
@ -2644,7 +2644,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 333px; background: red; border-radius: 20px; box-shadow: -5px 0 5px green; overflow: hidden;"
|
||||
>
|
||||
<div
|
||||
@ -2828,7 +2828,7 @@ HTMLCollection [
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -2837,7 +2837,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-left-appear ant-drawer-panel-motion-left-appear-active ant-drawer-panel-motion-left"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -2909,7 +2909,7 @@ exports[`renders ./components/drawer/demo/render-in-current.md extend context co
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -2918,7 +2918,7 @@ exports[`renders ./components/drawer/demo/render-in-current.md extend context co
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -3083,7 +3083,7 @@ HTMLCollection [
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -3092,7 +3092,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 378px;"
|
||||
>
|
||||
<div
|
||||
@ -3315,7 +3315,7 @@ HTMLCollection [
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask ant-drawer-mask-motion-appear ant-drawer-mask-motion-appear-active ant-drawer-mask-motion"
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
@ -3324,7 +3324,7 @@ HTMLCollection [
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper ant-drawer-panel-motion-right-appear ant-drawer-panel-motion-right-appear-active ant-drawer-panel-motion-right"
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="width: 640px;"
|
||||
>
|
||||
<div
|
||||
|
@ -9,6 +9,8 @@ jest.mock('rc-drawer', () => {
|
||||
...props,
|
||||
open: true,
|
||||
getContainer: false,
|
||||
maskMotion: null,
|
||||
motion: null,
|
||||
};
|
||||
return <MockDrawer {...newProps} />;
|
||||
};
|
||||
|
@ -141,6 +141,7 @@ function Drawer({
|
||||
motionAppear: true,
|
||||
motionEnter: true,
|
||||
motionLeave: true,
|
||||
motionDeadline: 500,
|
||||
};
|
||||
|
||||
const panelMotion: RcDrawerProps['motion'] = motionPlacement => ({
|
||||
@ -148,6 +149,7 @@ function Drawer({
|
||||
motionAppear: true,
|
||||
motionEnter: true,
|
||||
motionLeave: true,
|
||||
motionDeadline: 500,
|
||||
});
|
||||
|
||||
// =========================== Render ===========================
|
||||
|
@ -1,106 +0,0 @@
|
||||
import { mount } from 'enzyme';
|
||||
import React from 'react';
|
||||
import Dropdown from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import Menu from '../../menu';
|
||||
|
||||
describe('DropdownButton', () => {
|
||||
mountTest(Dropdown.Button);
|
||||
rtlTest(Dropdown.Button);
|
||||
|
||||
it('pass appropriate props to Dropdown', () => {
|
||||
const props = {
|
||||
align: {
|
||||
offset: [10, 20],
|
||||
},
|
||||
overlay: (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
),
|
||||
disabled: false,
|
||||
trigger: ['hover'],
|
||||
visible: true,
|
||||
onVisibleChange: () => {},
|
||||
};
|
||||
|
||||
const wrapper = mount(<Dropdown.Button {...props} />);
|
||||
const dropdownProps = wrapper.find(Dropdown).props();
|
||||
|
||||
Object.keys(props).forEach(key => {
|
||||
expect(dropdownProps[key]).toBe(props[key]);
|
||||
});
|
||||
});
|
||||
|
||||
it("don't pass visible to Dropdown if it's not exits", () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const wrapper = mount(<Dropdown.Button overlay={menu} />);
|
||||
const dropdownProps = wrapper.find(Dropdown).props();
|
||||
|
||||
expect('visible' in dropdownProps).toBe(false);
|
||||
});
|
||||
|
||||
it('should support href like Button', () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const wrapper = mount(<Dropdown.Button overlay={menu} href="https://ant.design" />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('have static property for type detecting', () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const wrapper = mount(<Dropdown.Button overlay={menu} />);
|
||||
expect(wrapper.find(Dropdown.Button).type().__ANT_BUTTON).toBe(true);
|
||||
});
|
||||
|
||||
it('should pass mouseEnterDelay and mouseLeaveDelay to Dropdown', () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const wrapper = mount(
|
||||
<Dropdown.Button mouseEnterDelay={1} mouseLeaveDelay={2} overlay={menu} />,
|
||||
);
|
||||
expect(wrapper.find('Dropdown').props().mouseEnterDelay).toBe(1);
|
||||
expect(wrapper.find('Dropdown').props().mouseLeaveDelay).toBe(2);
|
||||
});
|
||||
|
||||
it('should support overlayClassName and overlayStyle', () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const wrapper = mount(
|
||||
<Dropdown.Button
|
||||
overlayClassName="className"
|
||||
overlayStyle={{ color: 'red' }}
|
||||
overlay={menu}
|
||||
visible
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find('.ant-dropdown').getDOMNode().className).toContain('className');
|
||||
expect(wrapper.find('.ant-dropdown').getDOMNode().style.color).toContain('red');
|
||||
});
|
||||
|
||||
it('should support loading', () => {
|
||||
const wrapper = mount(<Dropdown.Button loading />);
|
||||
|
||||
expect(wrapper.find('.ant-dropdown-button .ant-btn-loading').getDOMNode().className).toContain(
|
||||
'ant-btn',
|
||||
);
|
||||
});
|
||||
});
|
117
components/dropdown/__tests__/dropdown-button.test.tsx
Normal file
117
components/dropdown/__tests__/dropdown-button.test.tsx
Normal file
@ -0,0 +1,117 @@
|
||||
import React from 'react';
|
||||
import DropdownButton from '../dropdown-button';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import Menu from '../../menu';
|
||||
import type { DropdownProps } from '../dropdown';
|
||||
import { render } from '../../../tests/utils';
|
||||
|
||||
let dropdownProps: DropdownProps;
|
||||
jest.mock('../dropdown', () => {
|
||||
const ActualDropdown = jest.requireActual('../dropdown');
|
||||
const ActualDropdownComponent = ActualDropdown.default;
|
||||
const h: typeof React = jest.requireActual('react');
|
||||
|
||||
const mockedDropdown = (props: DropdownProps) => {
|
||||
dropdownProps = props;
|
||||
const { children, ...restProps } = props;
|
||||
return h.createElement(ActualDropdownComponent, { ...restProps }, children);
|
||||
};
|
||||
mockedDropdown.defaultProps = ActualDropdownComponent.defaultProps;
|
||||
mockedDropdown.Button = ActualDropdownComponent.Button;
|
||||
|
||||
return {
|
||||
...ActualDropdown,
|
||||
__esModule: true,
|
||||
default: mockedDropdown,
|
||||
};
|
||||
});
|
||||
|
||||
describe('DropdownButton', () => {
|
||||
mountTest(DropdownButton);
|
||||
rtlTest(DropdownButton);
|
||||
|
||||
it('pass appropriate props to Dropdown', () => {
|
||||
const props: DropdownProps = {
|
||||
align: {
|
||||
offset: [10, 20],
|
||||
},
|
||||
overlay: (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
),
|
||||
disabled: false,
|
||||
trigger: ['hover'],
|
||||
visible: true,
|
||||
onVisibleChange: () => {},
|
||||
};
|
||||
|
||||
render(<DropdownButton {...props} />);
|
||||
|
||||
Object.keys(props).forEach((key: keyof DropdownProps) => {
|
||||
expect(dropdownProps[key]).toBe(props[key]);
|
||||
});
|
||||
});
|
||||
|
||||
it("don't pass visible to Dropdown if it's not exits", () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
render(<DropdownButton overlay={menu} />);
|
||||
expect('visible' in dropdownProps).toBe(false);
|
||||
});
|
||||
|
||||
it('should support href like Button', () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const { asFragment } = render(<DropdownButton overlay={menu} href="https://ant.design" />);
|
||||
expect(asFragment().firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('have static property for type detecting', () => {
|
||||
expect(DropdownButton.__ANT_BUTTON).toBe(true);
|
||||
});
|
||||
|
||||
it('should pass mouseEnterDelay and mouseLeaveDelay to Dropdown', () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
render(<DropdownButton mouseEnterDelay={1} mouseLeaveDelay={2} overlay={menu} />);
|
||||
expect(dropdownProps.mouseEnterDelay).toBe(1);
|
||||
expect(dropdownProps.mouseLeaveDelay).toBe(2);
|
||||
});
|
||||
|
||||
it('should support overlayClassName and overlayStyle', () => {
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const { container } = render(
|
||||
<DropdownButton
|
||||
overlayClassName="className"
|
||||
overlayStyle={{ color: 'red' }}
|
||||
overlay={menu}
|
||||
visible
|
||||
/>,
|
||||
);
|
||||
expect(container.querySelector('.ant-dropdown')?.classList).toContain('className');
|
||||
expect((container.querySelector('.ant-dropdown') as HTMLElement).style.color).toContain('red');
|
||||
});
|
||||
|
||||
it('should support loading', () => {
|
||||
const { container } = render(<DropdownButton overlay={<div />} loading />);
|
||||
|
||||
expect(container.querySelector('.ant-dropdown-button .ant-btn-loading')?.classList).toContain(
|
||||
'ant-btn',
|
||||
);
|
||||
});
|
||||
});
|
@ -1,44 +1,61 @@
|
||||
import { mount } from 'enzyme';
|
||||
import React from 'react';
|
||||
import type { TriggerProps } from 'rc-trigger';
|
||||
import Dropdown from '..';
|
||||
import type { DropDownProps } from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { act, fireEvent, render, sleep } from '../../../tests/utils';
|
||||
import Menu from '../../menu';
|
||||
|
||||
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('Dropdown', () => {
|
||||
mountTest(() => (
|
||||
<Dropdown menu={<Menu />}>
|
||||
<Dropdown overlay={<Menu />}>
|
||||
<span />
|
||||
</Dropdown>
|
||||
));
|
||||
|
||||
rtlTest(() => (
|
||||
<Dropdown menu={<Menu />}>
|
||||
<Dropdown overlay={<Menu />}>
|
||||
<span />
|
||||
</Dropdown>
|
||||
));
|
||||
|
||||
it('overlay is function and has custom transitionName', () => {
|
||||
const wrapper = mount(
|
||||
const { asFragment } = render(
|
||||
<Dropdown overlay={() => <div>menu</div>} transitionName="move-up" visible>
|
||||
<button type="button">button</button>
|
||||
</Dropdown>,
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(Array.from(asFragment().childNodes)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('overlay is string', () => {
|
||||
const wrapper = mount(
|
||||
<Dropdown overlay="string" visible>
|
||||
const { asFragment } = render(
|
||||
<Dropdown overlay={'string' as any} visible>
|
||||
<button type="button">button</button>
|
||||
</Dropdown>,
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(Array.from(asFragment().childNodes)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('support Menu expandIcon', async () => {
|
||||
const props = {
|
||||
const props: DropDownProps = {
|
||||
overlay: (
|
||||
<Menu expandIcon={<span id="customExpandIcon" />}>
|
||||
<Menu.Item key="1">foo</Menu.Item>
|
||||
@ -51,23 +68,23 @@ describe('Dropdown', () => {
|
||||
getPopupContainer: node => node,
|
||||
};
|
||||
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Dropdown {...props}>
|
||||
<button type="button">button</button>
|
||||
</Dropdown>,
|
||||
);
|
||||
await sleep(500);
|
||||
expect(wrapper.find(Dropdown).find('#customExpandIcon').length).toBe(1);
|
||||
expect(container.querySelectorAll('#customExpandIcon').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should warn if use topCenter or bottomCenter', () => {
|
||||
const error = jest.spyOn(console, 'error');
|
||||
mount(
|
||||
render(
|
||||
<div>
|
||||
<Dropdown overlay="123" placement="bottomCenter">
|
||||
<Dropdown overlay={'123' as any} placement="bottomCenter">
|
||||
<button type="button">bottomCenter</button>
|
||||
</Dropdown>
|
||||
<Dropdown overlay="123" placement="topCenter">
|
||||
<Dropdown overlay={'123' as any} placement="topCenter">
|
||||
<button type="button">topCenter</button>
|
||||
</Dropdown>
|
||||
</div>,
|
||||
@ -82,13 +99,13 @@ describe('Dropdown', () => {
|
||||
|
||||
// zombieJ: when replaced with react test lib, it may be mock fully content
|
||||
it('dropdown should support auto adjust placement', () => {
|
||||
const wrapper = mount(
|
||||
render(
|
||||
<Dropdown overlay={<div>menu</div>} visible>
|
||||
<button type="button">button</button>
|
||||
</Dropdown>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('Trigger').prop('builtinPlacements')).toEqual(
|
||||
expect(triggerProps.builtinPlacements).toEqual(
|
||||
expect.objectContaining({
|
||||
bottomLeft: expect.objectContaining({
|
||||
overflow: {
|
||||
@ -104,7 +121,7 @@ describe('Dropdown', () => {
|
||||
jest.useFakeTimers();
|
||||
const { container } = render(
|
||||
<Dropdown
|
||||
trigger="click"
|
||||
trigger={['click']}
|
||||
overlay={
|
||||
<Menu
|
||||
items={[
|
||||
@ -127,13 +144,13 @@ describe('Dropdown', () => {
|
||||
);
|
||||
|
||||
// Open
|
||||
fireEvent.click(container.querySelector('a'));
|
||||
fireEvent.click(container.querySelector('a')!);
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
});
|
||||
|
||||
// Close
|
||||
fireEvent.click(container.querySelector('.ant-dropdown-menu-item'));
|
||||
fireEvent.click(container.querySelector('.ant-dropdown-menu-item')!);
|
||||
|
||||
// Force Motion move on
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
@ -143,7 +160,7 @@ describe('Dropdown', () => {
|
||||
}
|
||||
|
||||
// Motion End
|
||||
fireEvent.animationEnd(container.querySelector('.ant-slide-up-leave-active'));
|
||||
fireEvent.animationEnd(container.querySelector('.ant-slide-up-leave-active')!);
|
||||
|
||||
expect(container.querySelector('.ant-dropdown-hidden')).toBeTruthy();
|
||||
|
@ -3,17 +3,17 @@
|
||||
exports[`Grid renders wrapped Col correctly 1`] = `
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-10px;margin-right:-10px"
|
||||
style="margin-left: -10px; margin-right: -10px;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-col ant-col-12"
|
||||
style="padding-left:10px;padding-right:10px"
|
||||
style="padding-left: 10px; padding-right: 10px;"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-12"
|
||||
style="padding-left:10px;padding-right:10px"
|
||||
style="padding-left: 10px; padding-right: 10px;"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
@ -45,6 +45,6 @@ exports[`Grid should render Row 1`] = `
|
||||
exports[`Grid when typeof gutter is object array in large screen 1`] = `
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-20px;margin-right:-20px;margin-top:-200px;margin-bottom:-200px"
|
||||
style="margin: -200px -20px -200px -20px;"
|
||||
/>
|
||||
`;
|
@ -1,7 +1,7 @@
|
||||
import { mount } from 'enzyme';
|
||||
import React, { memo, useContext, useRef, useState } from 'react';
|
||||
import Row from '../row';
|
||||
import RowContext from '../RowContext';
|
||||
import { render, fireEvent } from '../../../tests/utils';
|
||||
|
||||
const CacheInner = memo(() => {
|
||||
const countRef = useRef(0);
|
||||
@ -33,16 +33,16 @@ const CacheOuter = () => {
|
||||
};
|
||||
|
||||
it('Cached RowContext is working', () => {
|
||||
const wrapper = mount(<CacheOuter />);
|
||||
const childCount = wrapper.find('#child_count').text();
|
||||
const { container } = render(<CacheOuter />);
|
||||
const childCount = container.querySelector('#child_count')?.textContent;
|
||||
|
||||
wrapper.find('#parent_btn').at(0).simulate('click');
|
||||
expect(wrapper.find('#parent_count').text()).toBe('2');
|
||||
fireEvent.click(container.querySelector('#parent_btn')!);
|
||||
expect(container.querySelector('#parent_count')?.textContent).toBe('2');
|
||||
// child component won't rerender
|
||||
expect(wrapper.find('#child_count').text()).toBe(childCount);
|
||||
expect(container.querySelector('#child_count')?.textContent).toBe(childCount);
|
||||
|
||||
wrapper.find('#parent_btn').at(0).simulate('click');
|
||||
expect(wrapper.find('#parent_count').text()).toBe('3');
|
||||
fireEvent.click(container.querySelector('#parent_btn')!);
|
||||
expect(container.querySelector('#parent_count')?.textContent).toBe('3');
|
||||
// child component won't rerender
|
||||
expect(wrapper.find('#child_count').text()).toBe(childCount);
|
||||
expect(container.querySelector('#child_count')?.textContent).toBe(childCount);
|
||||
});
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { mount } from 'enzyme';
|
||||
import React from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { Col, Row } from '..';
|
||||
@ -22,19 +21,15 @@ describe('Grid.Gap', () => {
|
||||
});
|
||||
|
||||
it('should use gap', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Row gutter={[16, 8]}>
|
||||
<Col />
|
||||
</Row>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-row').props().style).toEqual(
|
||||
expect.objectContaining({
|
||||
marginLeft: -8,
|
||||
rowGap: 8,
|
||||
marginRight: -8,
|
||||
}),
|
||||
);
|
||||
expect((container.querySelector('.ant-row') as HTMLElement)!.style.marginLeft).toEqual('-8px');
|
||||
expect((container.querySelector('.ant-row') as HTMLElement)!.style.marginRight).toEqual('-8px');
|
||||
expect((container.querySelector('.ant-row') as HTMLElement)!.style.rowGap).toEqual('8px');
|
||||
});
|
||||
|
||||
it('not break ssr', () => {
|
@ -1,127 +0,0 @@
|
||||
import { mount, render } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Col, Row } from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import ResponsiveObserve from '../../_util/responsiveObserve';
|
||||
import useBreakpoint from '../hooks/useBreakpoint';
|
||||
|
||||
describe('Grid', () => {
|
||||
mountTest(Row);
|
||||
mountTest(Col);
|
||||
|
||||
rtlTest(Row);
|
||||
rtlTest(Col);
|
||||
|
||||
it('should render Col', () => {
|
||||
const wrapper = render(<Col span={2} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render Row', () => {
|
||||
const wrapper = render(<Row />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('when typeof gutter is object', () => {
|
||||
const wrapper = mount(<Row gutter={{ xs: 8, sm: 16, md: 24 }} />);
|
||||
expect(wrapper.find('div').first().props().style).toEqual(
|
||||
expect.objectContaining({
|
||||
marginLeft: -4,
|
||||
marginRight: -4,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('when typeof gutter is object array', () => {
|
||||
const wrapper = mount(
|
||||
<Row
|
||||
gutter={[
|
||||
{ xs: 8, sm: 16, md: 24, lg: 32, xl: 40 },
|
||||
{ xs: 8, sm: 16, md: 24, lg: 32, xl: 40 },
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find('div').first().props().style).toEqual(
|
||||
expect.objectContaining({
|
||||
marginLeft: -4,
|
||||
marginRight: -4,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('when typeof gutter is object array in large screen', () => {
|
||||
const wrapper = render(
|
||||
<Row
|
||||
gutter={[
|
||||
{ xs: 8, sm: 16, md: 24, lg: 32, xl: 40 },
|
||||
{ xs: 8, sm: 16, md: 24, lg: 100, xl: 400 },
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders wrapped Col correctly', () => {
|
||||
const MyCol = () => <Col span={12} />;
|
||||
const wrapper = render(
|
||||
<Row gutter={20}>
|
||||
<div>
|
||||
<Col span={12} />
|
||||
</div>
|
||||
<MyCol />
|
||||
</Row>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('ResponsiveObserve.unsubscribe should be called when unmounted', () => {
|
||||
const Unmount = jest.spyOn(ResponsiveObserve, 'unsubscribe');
|
||||
const wrapper = mount(<Row gutter={{ xs: 20 }} />);
|
||||
act(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
expect(Unmount).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should work correct when gutter is object', () => {
|
||||
const wrapper = mount(<Row gutter={{ xs: 20 }} />);
|
||||
expect(wrapper.find('div').prop('style')).toEqual({
|
||||
marginLeft: -10,
|
||||
marginRight: -10,
|
||||
});
|
||||
});
|
||||
|
||||
it('should work current when gutter is array', () => {
|
||||
const wrapper = mount(<Row gutter={[16, 20]} />);
|
||||
expect(wrapper.find('div').prop('style')).toEqual({
|
||||
marginLeft: -8,
|
||||
marginRight: -8,
|
||||
marginTop: -10,
|
||||
marginBottom: -10,
|
||||
});
|
||||
});
|
||||
|
||||
// By jsdom mock, actual jsdom not implemented matchMedia
|
||||
// https://jestjs.io/docs/en/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
|
||||
it('should work with useBreakpoint', () => {
|
||||
function Demo() {
|
||||
const screens = useBreakpoint();
|
||||
|
||||
return JSON.stringify(screens);
|
||||
}
|
||||
const wrapper = mount(<Demo />);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
JSON.stringify({
|
||||
xs: true,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: false,
|
||||
xxl: false,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
146
components/grid/__tests__/index.test.tsx
Normal file
146
components/grid/__tests__/index.test.tsx
Normal file
@ -0,0 +1,146 @@
|
||||
import React from 'react';
|
||||
import { Col, Row } from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import ResponsiveObserve from '../../_util/responsiveObserve';
|
||||
import useBreakpoint from '../hooks/useBreakpoint';
|
||||
import { render, act } from '../../../tests/utils';
|
||||
|
||||
describe('Grid', () => {
|
||||
mountTest(Row);
|
||||
mountTest(Col);
|
||||
|
||||
rtlTest(Row);
|
||||
rtlTest(Col);
|
||||
|
||||
afterEach(() => {
|
||||
ResponsiveObserve.unregister();
|
||||
});
|
||||
|
||||
it('should render Col', () => {
|
||||
const { asFragment } = render(<Col span={2} />);
|
||||
expect(asFragment().firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render Row', () => {
|
||||
const { asFragment } = render(<Row />);
|
||||
expect(asFragment().firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('when typeof gutter is object', () => {
|
||||
const { container } = render(<Row gutter={{ xs: 8, sm: 16, md: 24 }} />);
|
||||
expect(container.querySelector('div')!.style.marginLeft).toEqual('-4px');
|
||||
expect(container.querySelector('div')!.style.marginRight).toEqual('-4px');
|
||||
});
|
||||
|
||||
it('when typeof gutter is object array', () => {
|
||||
const { container } = render(
|
||||
<Row
|
||||
gutter={[
|
||||
{ xs: 8, sm: 16, md: 24, lg: 32, xl: 40 },
|
||||
{ xs: 8, sm: 16, md: 24, lg: 32, xl: 40 },
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
expect(container.querySelector('div')!.style.marginLeft).toEqual('-4px');
|
||||
expect(container.querySelector('div')!.style.marginRight).toEqual('-4px');
|
||||
});
|
||||
|
||||
it('when typeof gutter is object array in large screen', () => {
|
||||
jest.spyOn(window, 'matchMedia').mockImplementation(
|
||||
query =>
|
||||
({
|
||||
addListener: (cb: (e: { matches: boolean }) => void) => {
|
||||
cb({ matches: query === '(min-width: 1200px)' });
|
||||
},
|
||||
removeListener: jest.fn(),
|
||||
matches: query === '(min-width: 1200px)',
|
||||
} as any),
|
||||
);
|
||||
|
||||
const { container, asFragment } = render(
|
||||
<Row
|
||||
gutter={[
|
||||
{ xs: 8, sm: 16, md: 24, lg: 32, xl: 40 },
|
||||
{ xs: 8, sm: 16, md: 24, lg: 100, xl: 400 },
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
expect(asFragment().firstChild).toMatchSnapshot();
|
||||
|
||||
expect(container.querySelector('div')!.style.marginLeft).toEqual('-20px');
|
||||
expect(container.querySelector('div')!.style.marginRight).toEqual('-20px');
|
||||
expect(container.querySelector('div')!.style.marginTop).toEqual('-200px');
|
||||
expect(container.querySelector('div')!.style.marginBottom).toEqual('-200px');
|
||||
});
|
||||
|
||||
it('renders wrapped Col correctly', () => {
|
||||
const MyCol = () => <Col span={12} />;
|
||||
const { asFragment } = render(
|
||||
<Row gutter={20}>
|
||||
<div>
|
||||
<Col span={12} />
|
||||
</div>
|
||||
<MyCol />
|
||||
</Row>,
|
||||
);
|
||||
|
||||
expect(asFragment().firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('ResponsiveObserve.unsubscribe should be called when unmounted', () => {
|
||||
const Unmount = jest.spyOn(ResponsiveObserve, 'unsubscribe');
|
||||
const { unmount } = render(<Row gutter={{ xs: 20 }} />);
|
||||
act(() => {
|
||||
unmount();
|
||||
});
|
||||
expect(Unmount).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should work correct when gutter is object', () => {
|
||||
const { container } = render(<Row gutter={{ xs: 20 }} />);
|
||||
expect(container.querySelector('div')!.style.marginLeft).toEqual('-10px');
|
||||
expect(container.querySelector('div')!.style.marginRight).toEqual('-10px');
|
||||
});
|
||||
|
||||
it('should work current when gutter is array', () => {
|
||||
const { container } = render(<Row gutter={[16, 20]} />);
|
||||
expect(container.querySelector('div')!.style.marginLeft).toEqual('-8px');
|
||||
expect(container.querySelector('div')!.style.marginRight).toEqual('-8px');
|
||||
expect(container.querySelector('div')!.style.marginTop).toEqual('-10px');
|
||||
expect(container.querySelector('div')!.style.marginBottom).toEqual('-10px');
|
||||
});
|
||||
|
||||
// By jsdom mock, actual jsdom not implemented matchMedia
|
||||
// https://jestjs.io/docs/en/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
|
||||
it('should work with useBreakpoint', () => {
|
||||
const matchMediaSpy = jest.spyOn(window, 'matchMedia');
|
||||
matchMediaSpy.mockImplementation(
|
||||
query =>
|
||||
({
|
||||
addListener: (cb: (e: { matches: boolean }) => void) => {
|
||||
cb({ matches: query === '(max-width: 575px)' });
|
||||
},
|
||||
removeListener: jest.fn(),
|
||||
matches: query === '(max-width: 575px)',
|
||||
} as any),
|
||||
);
|
||||
|
||||
let screensVar;
|
||||
function Demo() {
|
||||
const screens = useBreakpoint();
|
||||
screensVar = screens;
|
||||
return <div />;
|
||||
}
|
||||
render(<Demo />);
|
||||
|
||||
expect(screensVar).toEqual({
|
||||
xs: true,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: false,
|
||||
xxl: false,
|
||||
});
|
||||
});
|
||||
});
|
@ -1,34 +0,0 @@
|
||||
import { mount } from 'enzyme';
|
||||
import React from 'react';
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { Col, Row } from '..';
|
||||
|
||||
jest.mock('rc-util/lib/Dom/canUseDom', () => () => false);
|
||||
|
||||
describe('Grid.Server', () => {
|
||||
it('use compatible gap logic', () => {
|
||||
const wrapper = mount(
|
||||
<Row gutter={[8, 16]}>
|
||||
<Col />
|
||||
</Row>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-row').props().style).toEqual(
|
||||
expect.objectContaining({
|
||||
marginLeft: -4,
|
||||
marginRight: -4,
|
||||
marginTop: -8,
|
||||
marginBottom: -8,
|
||||
}),
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-col').props().style).toEqual(
|
||||
expect.objectContaining({
|
||||
paddingLeft: 4,
|
||||
paddingRight: 4,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
30
components/grid/__tests__/server.test.tsx
Normal file
30
components/grid/__tests__/server.test.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { Col, Row } from '..';
|
||||
import { render } from '../../../tests/utils';
|
||||
|
||||
jest.mock('rc-util/lib/Dom/canUseDom', () => () => false);
|
||||
|
||||
describe('Grid.Server', () => {
|
||||
it('use compatible gap logic', () => {
|
||||
const { container } = render(
|
||||
<Row gutter={[8, 16]}>
|
||||
<Col />
|
||||
</Row>,
|
||||
);
|
||||
|
||||
expect((container.querySelector('.ant-row') as HTMLElement)!.style.marginLeft).toEqual('-4px');
|
||||
expect((container.querySelector('.ant-row') as HTMLElement)!.style.marginRight).toEqual('-4px');
|
||||
expect((container.querySelector('.ant-row') as HTMLElement)!.style.marginTop).toEqual('-8px');
|
||||
expect((container.querySelector('.ant-row') as HTMLElement)!.style.marginBottom).toEqual(
|
||||
'-8px',
|
||||
);
|
||||
|
||||
expect((container.querySelector('.ant-col') as HTMLElement)!.style.paddingLeft).toEqual('4px');
|
||||
expect((container.querySelector('.ant-col') as HTMLElement)!.style.paddingRight).toEqual('4px');
|
||||
expect((container.querySelector('.ant-col') as HTMLElement)!.style.paddingTop).toEqual('8px');
|
||||
expect((container.querySelector('.ant-col') as HTMLElement)!.style.paddingBottom).toEqual(
|
||||
'8px',
|
||||
);
|
||||
});
|
||||
});
|
@ -59,7 +59,7 @@ const App: React.FC = () => {
|
||||
onChange={setGutterKey}
|
||||
marks={gutters}
|
||||
step={null}
|
||||
tipFormatter={value => value && gutters[value]}
|
||||
tooltip={{ formatter: value => value && gutters[value] }}
|
||||
/>
|
||||
</div>
|
||||
<span>Vertical Gutter (px): </span>
|
||||
@ -71,7 +71,7 @@ const App: React.FC = () => {
|
||||
onChange={setVgutterKey}
|
||||
marks={vgutters}
|
||||
step={null}
|
||||
tipFormatter={value => value && vgutters[value]}
|
||||
tooltip={{ formatter: value => value && vgutters[value] }}
|
||||
/>
|
||||
</div>
|
||||
<span>Column Count:</span>
|
||||
@ -83,7 +83,7 @@ const App: React.FC = () => {
|
||||
onChange={setColCountKey}
|
||||
marks={colCounts}
|
||||
step={null}
|
||||
tipFormatter={value => value && colCounts[value]}
|
||||
tooltip={{ formatter: value => value && colCounts[value] }}
|
||||
/>
|
||||
</div>
|
||||
<Row gutter={[gutters[gutterKey], vgutters[vgutterKey]]}>
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Menu Menu.Item with icon children auto wrap span 1`] = `
|
||||
Array [
|
||||
<DocumentFragment>
|
||||
<ul
|
||||
class="ant-menu ant-menu-root ant-menu-vertical"
|
||||
data-menu-list="true"
|
||||
@ -154,16 +154,16 @@ Array [
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>,
|
||||
</ul>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display: none;"
|
||||
/>,
|
||||
]
|
||||
/>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`Menu all types must be available in the "items" syntax 1`] = `
|
||||
Array [
|
||||
<DocumentFragment>
|
||||
<ul
|
||||
class="ant-menu ant-menu-root ant-menu-inline"
|
||||
data-menu-list="true"
|
||||
@ -315,12 +315,12 @@ Array [
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>,
|
||||
</ul>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display: none;"
|
||||
/>,
|
||||
]
|
||||
/>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`Menu rtl render component should be rendered correctly in RTL direction 1`] = `
|
||||
@ -381,7 +381,7 @@ Array [
|
||||
`;
|
||||
|
||||
exports[`Menu should controlled collapse work 1`] = `
|
||||
Array [
|
||||
<DocumentFragment>
|
||||
<ul
|
||||
class="ant-menu ant-menu-root ant-menu-inline"
|
||||
data-menu-list="true"
|
||||
@ -420,16 +420,16 @@ Array [
|
||||
Option 1
|
||||
</span>
|
||||
</li>
|
||||
</ul>,
|
||||
</ul>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display: none;"
|
||||
/>,
|
||||
]
|
||||
/>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`Menu should controlled collapse work 2`] = `
|
||||
Array [
|
||||
<DocumentFragment>
|
||||
<ul
|
||||
class="ant-menu ant-menu-root ant-menu-vertical ant-menu-inline-collapsed"
|
||||
data-menu-list="true"
|
||||
@ -468,10 +468,10 @@ Array [
|
||||
Option 1
|
||||
</span>
|
||||
</li>
|
||||
</ul>,
|
||||
</ul>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display: none;"
|
||||
/>,
|
||||
]
|
||||
/>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
@ -5,14 +5,12 @@ import {
|
||||
PieChartOutlined,
|
||||
UserOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { mount } from 'enzyme';
|
||||
import React, { useState } from 'react';
|
||||
import Menu from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { fireEvent, render, act } from '../../../tests/utils';
|
||||
import Layout from '../../layout';
|
||||
import Tooltip from '../../tooltip';
|
||||
import initCollapseMotion from '../../_util/motion';
|
||||
import { noop } from '../../_util/warning';
|
||||
|
||||
@ -137,7 +135,7 @@ describe('Menu', () => {
|
||||
});
|
||||
|
||||
it('If has select nested submenu item ,the menu items on the grandfather level should be highlight', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu defaultSelectedKeys={['1-3-2']} mode="vertical">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="1-1">Option 1</Menu.Item>
|
||||
@ -150,11 +148,11 @@ describe('Menu', () => {
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.find('li.ant-menu-submenu-selected').length).toBe(1);
|
||||
expect(container.querySelectorAll('li.ant-menu-submenu-selected').length).toBe(1);
|
||||
});
|
||||
|
||||
it('forceSubMenuRender', () => {
|
||||
const wrapper = mount(
|
||||
const { container, rerender } = render(
|
||||
<Menu mode="horizontal">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="1-1">
|
||||
@ -164,14 +162,22 @@ describe('Menu', () => {
|
||||
</Menu>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.bamboo').hostNodes()).toHaveLength(0);
|
||||
expect(container.querySelector('.bamboo')).toBeFalsy();
|
||||
|
||||
wrapper.setProps({ forceSubMenuRender: true });
|
||||
expect(wrapper.find('.bamboo').hostNodes()).toHaveLength(1);
|
||||
rerender(
|
||||
<Menu mode="horizontal" forceSubMenuRender>
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="1-1">
|
||||
<span className="bamboo" />
|
||||
</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>,
|
||||
);
|
||||
expect(container.querySelector('.bamboo')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should accept defaultOpenKeys in mode horizontal', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu defaultOpenKeys={['1']} mode="horizontal">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
@ -180,11 +186,15 @@ describe('Menu', () => {
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.exists('.ant-menu-sub')).toBeFalsy();
|
||||
|
||||
expect(
|
||||
container.querySelector('.ant-menu-submenu-open').querySelector('.ant-menu-submenu-title')
|
||||
.textContent,
|
||||
).toEqual('submenu1');
|
||||
});
|
||||
|
||||
it('should accept defaultOpenKeys in mode inline', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu defaultOpenKeys={['1']} mode="inline">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
@ -193,11 +203,15 @@ describe('Menu', () => {
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
|
||||
expect(
|
||||
container.querySelector('.ant-menu-submenu-open').querySelector('.ant-menu-submenu-title')
|
||||
.textContent,
|
||||
).toEqual('submenu1');
|
||||
});
|
||||
|
||||
it('should accept defaultOpenKeys in mode vertical', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu defaultOpenKeys={['1']} mode="vertical">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
@ -206,11 +220,11 @@ describe('Menu', () => {
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.find('PopupTrigger').first().prop('visible')).toBeTruthy();
|
||||
expect(container.querySelector('.ant-menu-sub')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should accept openKeys in mode horizontal', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu openKeys={['1']} mode="horizontal">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
@ -219,11 +233,14 @@ describe('Menu', () => {
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.find('PopupTrigger').first().prop('visible')).toBeTruthy();
|
||||
triggerAllTimer();
|
||||
expect(container.querySelector('div.ant-menu-submenu-popup')).not.toHaveClass(
|
||||
'ant-menu-submenu-hidden',
|
||||
);
|
||||
});
|
||||
|
||||
it('should accept openKeys in mode inline', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu openKeys={['1']} mode="inline">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
@ -232,11 +249,11 @@ describe('Menu', () => {
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.find('InlineSubMenuList').first().prop('open')).toBeTruthy();
|
||||
expect(container.querySelector('ul.ant-menu-sub')).not.toHaveClass('ant-menu-hidden');
|
||||
});
|
||||
|
||||
it('should accept openKeys in mode vertical', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu openKeys={['1']} mode="vertical">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
@ -245,7 +262,10 @@ describe('Menu', () => {
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.find('PopupTrigger').first().prop('visible')).toBeTruthy();
|
||||
triggerAllTimer();
|
||||
expect(container.querySelector('div.ant-menu-submenu-popup')).not.toHaveClass(
|
||||
'ant-menu-submenu-hidden',
|
||||
);
|
||||
});
|
||||
|
||||
it('test submenu in mode horizontal', async () => {
|
||||
@ -359,8 +379,8 @@ describe('Menu', () => {
|
||||
});
|
||||
|
||||
it('should always follow openKeys when inlineCollapsed is switched', () => {
|
||||
const wrapper = mount(
|
||||
<Menu defaultOpenKeys={['1']} mode="inline">
|
||||
const Demo = props => (
|
||||
<Menu defaultOpenKeys={['1']} mode="inline" {...props}>
|
||||
<Menu.Item key="menu1" icon={<InboxOutlined />}>
|
||||
Option
|
||||
</Menu.Item>
|
||||
@ -368,30 +388,34 @@ describe('Menu', () => {
|
||||
<Menu.Item key="submenu1">Option</Menu.Item>
|
||||
<Menu.Item key="submenu2">Option</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>,
|
||||
</Menu>
|
||||
);
|
||||
const { container, rerender } = render(<Demo />);
|
||||
|
||||
expect(wrapper.find('InlineSubMenuList').prop('open')).toBeTruthy();
|
||||
|
||||
expect(container.querySelector('li.ant-menu-submenu-inline')).toHaveClass(
|
||||
'ant-menu-submenu-open',
|
||||
);
|
||||
// inlineCollapsed
|
||||
wrapper.setProps({ inlineCollapsed: true });
|
||||
rerender(<Demo inlineCollapsed />);
|
||||
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
});
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('ul.ant-menu-root').hasClass('ant-menu-vertical')).toBeTruthy();
|
||||
expect(wrapper.find('PopupTrigger').prop('visible')).toBeFalsy();
|
||||
expect(container.querySelector('ul.ant-menu-root')).toHaveClass('ant-menu-vertical');
|
||||
expect(container.querySelector('.ant-menu-submenu-popup')).toBeFalsy();
|
||||
|
||||
// !inlineCollapsed
|
||||
wrapper.setProps({ inlineCollapsed: false });
|
||||
rerender(<Demo inlineCollapsed={false} />);
|
||||
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
});
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('ul.ant-menu-sub').last().hasClass('ant-menu-inline')).toBeTruthy();
|
||||
expect(wrapper.find('InlineSubMenuList').prop('open')).toBeTruthy();
|
||||
expect(container.querySelector('ul.ant-menu-sub')).toHaveClass('ant-menu-inline');
|
||||
expect(container.querySelector('li.ant-menu-submenu-inline')).toHaveClass(
|
||||
'ant-menu-submenu-open',
|
||||
);
|
||||
});
|
||||
|
||||
it('inlineCollapsed should works well when specify a not existed default openKeys', () => {
|
||||
@ -431,7 +455,7 @@ describe('Menu', () => {
|
||||
});
|
||||
|
||||
it('inlineCollapsed Menu.Item Tooltip can be removed', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu
|
||||
defaultOpenKeys={['not-existed']}
|
||||
mode="inline"
|
||||
@ -456,12 +480,19 @@ describe('Menu', () => {
|
||||
</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.find(Menu.Item).at(0).find(Tooltip).props().title).toBe('item');
|
||||
expect(wrapper.find(Menu.Item).at(1).find(Tooltip).props().title).toBe('title');
|
||||
expect(wrapper.find(Menu.Item).at(2).find(Tooltip).props().title).toBe('item');
|
||||
expect(wrapper.find(Menu.Item).at(3).find(Tooltip).props().title).toBe(null);
|
||||
expect(wrapper.find(Menu.Item).at(4).find(Tooltip).props().title).toBe('');
|
||||
expect(wrapper.find(Menu.Item).at(4).find(Tooltip).props().title).toBe('');
|
||||
fireEvent.mouseEnter(container.querySelectorAll('li.ant-menu-item')[0]);
|
||||
fireEvent.mouseEnter(container.querySelectorAll('li.ant-menu-item')[1]);
|
||||
fireEvent.mouseEnter(container.querySelectorAll('li.ant-menu-item')[2]);
|
||||
fireEvent.mouseEnter(container.querySelectorAll('li.ant-menu-item')[3]);
|
||||
fireEvent.mouseEnter(container.querySelectorAll('li.ant-menu-item')[4]);
|
||||
fireEvent.mouseEnter(container.querySelectorAll('li.ant-menu-item')[5]);
|
||||
|
||||
triggerAllTimer();
|
||||
// when title is null or '' and false, tooltip will not render.
|
||||
expect(container.querySelectorAll('.ant-tooltip-inner').length).toBe(3);
|
||||
expect(container.querySelectorAll('.ant-tooltip-inner')[0].textContent).toBe('item');
|
||||
expect(container.querySelectorAll('.ant-tooltip-inner')[1].textContent).toBe('title');
|
||||
expect(container.querySelectorAll('.ant-tooltip-inner')[2].textContent).toBe('item');
|
||||
});
|
||||
|
||||
describe('open submenu when click submenu title', () => {
|
||||
@ -612,7 +643,7 @@ describe('Menu', () => {
|
||||
});
|
||||
|
||||
it('inline title', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu mode="inline" inlineCollapsed>
|
||||
<Menu.Item key="1" title="bamboo lucky" icon={<PieChartOutlined />}>
|
||||
Option 1
|
||||
@ -624,13 +655,10 @@ describe('Menu', () => {
|
||||
</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
|
||||
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
||||
fireEvent.mouseEnter(container.querySelector('.ant-menu-item'));
|
||||
triggerAllTimer();
|
||||
wrapper.update();
|
||||
|
||||
const text = wrapper.find('.ant-tooltip-inner').text();
|
||||
expect(text).toBe('bamboo lucky');
|
||||
expect(container.querySelector('.ant-tooltip-inner').textContent).toBe('bamboo lucky');
|
||||
});
|
||||
|
||||
it('render correctly when using with Layout.Sider', () => {
|
||||
@ -659,34 +687,34 @@ describe('Menu', () => {
|
||||
);
|
||||
}
|
||||
}
|
||||
const wrapper = mount(<Demo />);
|
||||
expect(wrapper.find(Menu).at(0).getDOMNode().classList.contains('ant-menu-inline')).toBe(true);
|
||||
wrapper.find('.ant-menu-submenu-title').simulate('click');
|
||||
wrapper.find('.ant-layout-sider-trigger').simulate('click');
|
||||
const { container } = render(<Demo />);
|
||||
|
||||
expect(container.querySelector('ul.ant-menu-root')).toHaveClass('ant-menu-inline');
|
||||
|
||||
fireEvent.click(container.querySelector('.ant-menu-submenu-title'));
|
||||
fireEvent.click(container.querySelector('.ant-layout-sider-trigger'));
|
||||
triggerAllTimer();
|
||||
wrapper.update();
|
||||
expect(wrapper.find(Menu).getDOMNode().classList.contains('ant-menu-inline-collapsed')).toBe(
|
||||
true,
|
||||
);
|
||||
wrapper.find(Menu).simulate('mouseenter');
|
||||
expect(wrapper.find(Menu).getDOMNode().classList.contains('ant-menu-inline')).toBe(false);
|
||||
expect(wrapper.find(Menu).getDOMNode().classList.contains('ant-menu-vertical')).toBe(true);
|
||||
expect(container.querySelector('ul.ant-menu-root')).toHaveClass('ant-menu-inline-collapsed');
|
||||
|
||||
fireEvent.mouseEnter(container.querySelector('ul.ant-menu-root'));
|
||||
expect(container.querySelector('ul.ant-menu-root')).not.toHaveClass('ant-menu-inline');
|
||||
expect(container.querySelector('ul.ant-menu-root')).toHaveClass('ant-menu-vertical');
|
||||
});
|
||||
|
||||
it('onMouseEnter should work', () => {
|
||||
const onMouseEnter = jest.fn();
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu onMouseEnter={onMouseEnter} defaultSelectedKeys={['test1']}>
|
||||
<Menu.Item key="test1">Navigation One</Menu.Item>
|
||||
<Menu.Item key="test2">Navigation Two</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
wrapper.find('ul.ant-menu-root').simulate('mouseenter');
|
||||
fireEvent.mouseEnter(container.querySelector('ul.ant-menu-root'));
|
||||
expect(onMouseEnter).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('MenuItem should not render Tooltip when inlineCollapsed is false', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu defaultSelectedKeys={['mail']} defaultOpenKeys={['mail']} mode="horizontal">
|
||||
<Menu.Item key="mail" icon={<MailOutlined />}>
|
||||
Navigation One
|
||||
@ -703,29 +731,27 @@ describe('Menu', () => {
|
||||
{ attachTo: div },
|
||||
);
|
||||
|
||||
wrapper.find('li.ant-menu-item').first().simulate('mouseenter');
|
||||
|
||||
fireEvent.mouseEnter(container.querySelector('li.ant-menu-item'));
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
});
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('.ant-tooltip-inner').length).toBe(0);
|
||||
expect(container.querySelectorAll('.ant-tooltip-inner').length).toBe(0);
|
||||
});
|
||||
|
||||
it('MenuItem should render icon and icon should be the first child when icon exists', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu>
|
||||
<Menu.Item key="mail" icon={<MailOutlined />}>
|
||||
Navigation One
|
||||
</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-item .anticon').hasClass('anticon-mail')).toBe(true);
|
||||
expect(container.querySelector('.ant-menu-item .anticon')).toHaveClass('anticon-mail');
|
||||
});
|
||||
|
||||
it('should controlled collapse work', () => {
|
||||
const wrapper = mount(
|
||||
const { asFragment, rerender } = render(
|
||||
<Menu mode="inline" inlineCollapsed={false}>
|
||||
<Menu.Item key="1" icon={<PieChartOutlined />}>
|
||||
Option 1
|
||||
@ -733,30 +759,34 @@ describe('Menu', () => {
|
||||
</Menu>,
|
||||
);
|
||||
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
|
||||
wrapper.setProps({ inlineCollapsed: true });
|
||||
rerender(
|
||||
<Menu mode="inline" inlineCollapsed>
|
||||
<Menu.Item key="1" icon={<PieChartOutlined />}>
|
||||
Option 1
|
||||
</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('not title if not collapsed', () => {
|
||||
jest.useFakeTimers();
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu mode="inline" inlineCollapsed={false}>
|
||||
<Menu.Item key="1" icon={<PieChartOutlined />}>
|
||||
Option 1
|
||||
</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
|
||||
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
||||
fireEvent.mouseEnter(container.querySelector('.ant-menu-item'));
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
});
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy();
|
||||
expect(container.querySelectorAll('.ant-tooltip-inner').length).toBeFalsy();
|
||||
|
||||
jest.useRealTimers();
|
||||
});
|
||||
@ -799,45 +829,42 @@ describe('Menu', () => {
|
||||
// https://github.com/ant-design/ant-design/issues/8587
|
||||
it('should keep selectedKeys in state when collapsed to 0px', () => {
|
||||
jest.useFakeTimers();
|
||||
const wrapper = mount(
|
||||
const Demo = props => (
|
||||
<Menu
|
||||
mode="inline"
|
||||
inlineCollapsed={false}
|
||||
defaultSelectedKeys={['1']}
|
||||
collapsedWidth={0}
|
||||
openKeys={['3']}
|
||||
{...props}
|
||||
>
|
||||
<Menu.Item key="1">Option 1</Menu.Item>
|
||||
<Menu.Item key="2">Option 2</Menu.Item>
|
||||
<Menu.SubMenu key="3" title="Option 3">
|
||||
<Menu.Item key="4">Option 4</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu>,
|
||||
</Menu>
|
||||
);
|
||||
expect(wrapper.find('li.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 1');
|
||||
wrapper.find('li.ant-menu-item').at(1).simulate('click');
|
||||
expect(wrapper.find('li.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 2');
|
||||
wrapper.setProps({ inlineCollapsed: true });
|
||||
|
||||
const { container, rerender } = render(<Demo />);
|
||||
expect(container.querySelector('li.ant-menu-item-selected').textContent).toBe('Option 1');
|
||||
fireEvent.click(container.querySelectorAll('li.ant-menu-item')[1]);
|
||||
expect(container.querySelector('li.ant-menu-item-selected').textContent).toBe('Option 2');
|
||||
|
||||
rerender(<Demo inlineCollapsed />);
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
});
|
||||
expect(container.querySelector('li.ant-menu-item-selected').textContent).toBe('O');
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('PopupTrigger')
|
||||
.map(node => node.prop('popupVisible'))
|
||||
.findIndex(node => !!node),
|
||||
).toBe(-1);
|
||||
rerender(<Demo inlineCollapsed={false} />);
|
||||
|
||||
wrapper.setProps({ inlineCollapsed: false });
|
||||
expect(wrapper.find('li.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 2');
|
||||
expect(container.querySelector('li.ant-menu-item-selected').textContent).toBe('Option 2');
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('Menu.Item with icon children auto wrap span', () => {
|
||||
const wrapper = mount(
|
||||
const { asFragment } = render(
|
||||
<Menu>
|
||||
<Menu.Item key="1" icon={<MailOutlined />}>
|
||||
Navigation One
|
||||
@ -849,7 +876,7 @@ describe('Menu', () => {
|
||||
<Menu.SubMenu key="4" icon={<MailOutlined />} title={<span>Navigation One</span>} />
|
||||
</Menu>,
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/23755
|
||||
@ -876,25 +903,29 @@ describe('Menu', () => {
|
||||
</>
|
||||
);
|
||||
}
|
||||
const wrapper = mount(<App />);
|
||||
wrapper.find('button').simulate('click');
|
||||
const { container } = render(<App />);
|
||||
fireEvent.click(container.querySelector('button'));
|
||||
expect(onOpenChange).toHaveBeenCalledWith([]);
|
||||
});
|
||||
|
||||
it('Use first char as Icon when collapsed', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu mode="inline" inlineCollapsed>
|
||||
<Menu.SubMenu title="Light" />
|
||||
<Menu.Item>Bamboo</Menu.Item>
|
||||
</Menu>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-menu-inline-collapsed-noicon').first().text()).toEqual('L');
|
||||
expect(wrapper.find('.ant-menu-inline-collapsed-noicon').last().text()).toEqual('B');
|
||||
expect(container.querySelectorAll('.ant-menu-inline-collapsed-noicon')[0].textContent).toEqual(
|
||||
'L',
|
||||
);
|
||||
expect(container.querySelectorAll('.ant-menu-inline-collapsed-noicon')[1].textContent).toEqual(
|
||||
'B',
|
||||
);
|
||||
});
|
||||
|
||||
it('divider should show', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu mode="vertical">
|
||||
<SubMenu key="sub1" title="Navigation One">
|
||||
<Menu.Item key="1">Option 1</Menu.Item>
|
||||
@ -910,8 +941,8 @@ describe('Menu', () => {
|
||||
</Menu>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('li.ant-menu-item-divider').length).toBe(2);
|
||||
expect(wrapper.find('li.ant-menu-item-divider-dashed').length).toBe(1);
|
||||
expect(container.querySelectorAll('li.ant-menu-item-divider').length).toBe(2);
|
||||
expect(container.querySelectorAll('li.ant-menu-item-divider-dashed').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should support ref', async () => {
|
||||
@ -927,7 +958,7 @@ describe('Menu', () => {
|
||||
});
|
||||
|
||||
it('expandIcon', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<Menu defaultOpenKeys={['1']} mode="inline" expandIcon={() => <span className="bamboo" />}>
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
@ -935,11 +966,11 @@ describe('Menu', () => {
|
||||
</Menu>,
|
||||
);
|
||||
|
||||
expect(wrapper.exists('.bamboo')).toBeTruthy();
|
||||
expect(container.querySelector('.bamboo')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('all types must be available in the "items" syntax', () => {
|
||||
const wrapper = mount(
|
||||
const { asFragment } = render(
|
||||
<Menu
|
||||
mode="inline"
|
||||
defaultOpenKeys={['submenu', 'group-submenu']}
|
||||
@ -977,12 +1008,12 @@ describe('Menu', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not warning deprecated message when items={undefined}', () => {
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||
mount(<Menu items={undefined} />);
|
||||
render(<Menu items={undefined} />);
|
||||
expect(errorSpy).not.toHaveBeenCalledWith(
|
||||
expect.stringContaining('`children` will be removed in next major version'),
|
||||
);
|
||||
|
@ -80,56 +80,6 @@ exports[`Slider should render in RTL direction 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Slider should show correct placement tooltip when set tooltipPlacement 1`] = `
|
||||
<div
|
||||
class="ant-tooltip ant-slider-tooltip ant-zoom-down-appear ant-zoom-down-appear-prepare ant-zoom-down"
|
||||
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"
|
||||
>
|
||||
30
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Slider should show correct placement tooltip when set tooltipPlacement 2`] = `
|
||||
<div
|
||||
class="ant-tooltip ant-slider-tooltip ant-zoom-down-leave ant-zoom-down-leave-start ant-zoom-down"
|
||||
style="pointer-events: none;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
30
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Slider should show tooltip when hovering slider handler 1`] = `
|
||||
<div
|
||||
class="ant-tooltip ant-slider-tooltip ant-zoom-down-appear ant-zoom-down-appear-prepare ant-zoom-down"
|
||||
|
@ -1,17 +1,42 @@
|
||||
import React from 'react';
|
||||
import Slider from '..';
|
||||
import type { SliderSingleProps } from '..';
|
||||
import focusTest from '../../../tests/shared/focusTest';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { sleep, render, fireEvent } from '../../../tests/utils';
|
||||
import { render, fireEvent, act } from '../../../tests/utils';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
import SliderTooltip from '../SliderTooltip';
|
||||
import type { TooltipProps } from '../../tooltip';
|
||||
|
||||
function tooltipProps(): TooltipProps {
|
||||
return (global as any).tooltipProps;
|
||||
}
|
||||
|
||||
jest.mock('../../tooltip', () => {
|
||||
const ReactReal = jest.requireActual('react');
|
||||
const Tooltip = jest.requireActual('../../tooltip');
|
||||
const TooltipComponent = Tooltip.default;
|
||||
return ReactReal.forwardRef((props: TooltipProps, ref: any) => {
|
||||
(global as any).tooltipProps = props;
|
||||
return <TooltipComponent {...props} ref={ref} />;
|
||||
});
|
||||
});
|
||||
|
||||
describe('Slider', () => {
|
||||
mountTest(Slider);
|
||||
rtlTest(Slider);
|
||||
focusTest(Slider, { testLib: true });
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllTimers();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should show tooltip when hovering slider handler', () => {
|
||||
const { container } = render(<Slider defaultValue={30} />);
|
||||
|
||||
@ -23,34 +48,58 @@ describe('Slider', () => {
|
||||
expect(document.querySelector('.ant-tooltip')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should show correct placement tooltip when set tooltipPlacement', () => {
|
||||
const { container } = render(<Slider vertical defaultValue={30} tooltipPlacement="left" />);
|
||||
describe('should show correct placement tooltip when set tooltipPlacement', () => {
|
||||
function test(name: string, props: Partial<SliderSingleProps>) {
|
||||
it(name, () => {
|
||||
const { container } = render(<Slider vertical defaultValue={30} {...props} />);
|
||||
|
||||
fireEvent.mouseEnter(container.querySelector('.ant-slider-handle')!);
|
||||
expect(document.querySelector('.ant-tooltip')).toMatchSnapshot();
|
||||
fireEvent.mouseEnter(container.querySelector('.ant-slider-handle')!);
|
||||
expect(tooltipProps().placement).toEqual('left');
|
||||
});
|
||||
}
|
||||
|
||||
fireEvent.mouseLeave(container.querySelector('.ant-slider-handle')!);
|
||||
expect(document.querySelector('.ant-tooltip')).toMatchSnapshot();
|
||||
test('new', { tooltip: { placement: 'left' } });
|
||||
test('legacy', { tooltipPlacement: 'left' });
|
||||
});
|
||||
|
||||
it('when tooltipVisible is true, tooltip should show always, or should never show', () => {
|
||||
const { container: container1 } = render(<Slider defaultValue={30} tooltipVisible />);
|
||||
expect(
|
||||
container1.querySelector('.ant-tooltip-content')!.className.includes('ant-tooltip-hidden'),
|
||||
).toBeFalsy();
|
||||
describe('when tooltip.open is true, tooltip should show always, or should never show', () => {
|
||||
function test(
|
||||
name: string,
|
||||
showProps: Partial<SliderSingleProps>,
|
||||
hideProps: Partial<SliderSingleProps>,
|
||||
) {
|
||||
it(name, () => {
|
||||
const { container, rerender } = render(<Slider defaultValue={30} {...showProps} />);
|
||||
expect(
|
||||
container.querySelector('.ant-tooltip-content')!.className.includes('ant-tooltip-hidden'),
|
||||
).toBeFalsy();
|
||||
|
||||
fireEvent.mouseEnter(container1.querySelector('.ant-slider-handle')!);
|
||||
expect(
|
||||
container1.querySelector('.ant-tooltip-content')!.className.includes('ant-tooltip-hidden'),
|
||||
).toBeFalsy();
|
||||
fireEvent.mouseEnter(container.querySelector('.ant-slider-handle')!);
|
||||
expect(
|
||||
container.querySelector('.ant-tooltip-content')!.className.includes('ant-tooltip-hidden'),
|
||||
).toBeFalsy();
|
||||
|
||||
fireEvent.click(container1.querySelector('.ant-slider-handle')!);
|
||||
expect(
|
||||
container1.querySelector('.ant-tooltip-content')!.className.includes('ant-tooltip-hidden'),
|
||||
).toBeFalsy();
|
||||
fireEvent.click(container.querySelector('.ant-slider-handle')!);
|
||||
expect(
|
||||
container.querySelector('.ant-tooltip-content')!.className.includes('ant-tooltip-hidden'),
|
||||
).toBeFalsy();
|
||||
|
||||
const { container: container2 } = render(<Slider defaultValue={30} tooltipVisible={false} />);
|
||||
expect(container2.querySelector('.ant-tooltip-content')!).toBeNull();
|
||||
// Force hide
|
||||
rerender(<Slider defaultValue={30} {...hideProps} />);
|
||||
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
});
|
||||
if (container.querySelector('.ant-zoom-down-leave-active')) {
|
||||
fireEvent.animationEnd(container.querySelector('.ant-zoom-down-leave-active')!);
|
||||
}
|
||||
|
||||
expect(container.querySelector('.ant-tooltip-hidden')!).toBeTruthy();
|
||||
});
|
||||
}
|
||||
|
||||
test('new', { tooltip: { open: true } }, { tooltip: { open: false } });
|
||||
test('legacy', { tooltipVisible: true }, { tooltipVisible: false });
|
||||
});
|
||||
|
||||
it('when step is null, thumb can only be slided to the specific mark', () => {
|
||||
@ -62,7 +111,12 @@ describe('Slider', () => {
|
||||
};
|
||||
|
||||
const { container } = render(
|
||||
<Slider marks={marks} defaultValue={intentionallyWrongValue} step={null} tooltipVisible />,
|
||||
<Slider
|
||||
marks={marks}
|
||||
defaultValue={intentionallyWrongValue}
|
||||
step={null}
|
||||
tooltip={{ open: true }}
|
||||
/>,
|
||||
);
|
||||
expect(container.querySelector('.ant-slider-handle')!.getAttribute('aria-valuenow')).toBe('48');
|
||||
});
|
||||
@ -75,7 +129,7 @@ describe('Slider', () => {
|
||||
};
|
||||
|
||||
const { container } = render(
|
||||
<Slider marks={marks} defaultValue={49} step={1} tooltipVisible />,
|
||||
<Slider marks={marks} defaultValue={49} step={1} tooltip={{ open: true }} />,
|
||||
);
|
||||
expect(container.querySelector('.ant-slider-handle')!.getAttribute('aria-valuenow')).toBe('49');
|
||||
});
|
||||
@ -88,7 +142,7 @@ describe('Slider', () => {
|
||||
};
|
||||
|
||||
const { container } = render(
|
||||
<Slider marks={marks} defaultValue={49} step={undefined} tooltipVisible />,
|
||||
<Slider marks={marks} defaultValue={49} step={undefined} tooltip={{ open: true }} />,
|
||||
);
|
||||
expect(container.querySelector('.ant-slider-handle')!.getAttribute('aria-valuenow')).toBe('49');
|
||||
});
|
||||
@ -96,7 +150,7 @@ describe('Slider', () => {
|
||||
it('should render in RTL direction', () => {
|
||||
const { container } = render(
|
||||
<ConfigProvider direction="rtl">
|
||||
<Slider defaultValue={30} tooltipVisible />
|
||||
<Slider defaultValue={30} tooltip={{ open: true }} />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
@ -114,18 +168,46 @@ describe('Slider', () => {
|
||||
/>,
|
||||
);
|
||||
ref.forcePopupAlign = jest.fn();
|
||||
await sleep(20);
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
});
|
||||
expect(ref.forcePopupAlign).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('tipFormatter should not crash with undefined value', () => {
|
||||
[undefined, null].forEach(value => {
|
||||
render(<Slider value={value as any} tooltipVisible />);
|
||||
render(<Slider value={value as any} tooltip={{ open: true }} />);
|
||||
});
|
||||
});
|
||||
it('step should not crash with undefined value', () => {
|
||||
[undefined, null].forEach(value => {
|
||||
render(<Slider step={value} tooltipVisible />);
|
||||
render(<Slider step={value} tooltip={{ open: true }} />);
|
||||
});
|
||||
});
|
||||
it('deprecated warning', () => {
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
const { rerender } = render(<Slider tooltipPrefixCls="xxx" />);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Slider] `tooltipPrefixCls` is deprecated which will be removed in next major version, please use `tooltip.prefixCls` instead.',
|
||||
);
|
||||
rerender(<Slider getTooltipPopupContainer={() => document.body} />);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Slider] `getTooltipPopupContainer` is deprecated which will be removed in next major version, please use `tooltip.getPopupContainer` instead.',
|
||||
);
|
||||
rerender(<Slider tipFormatter={v => v} />);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Slider] `tipFormatter` is deprecated which will be removed in next major version, please use `tooltip.formatter` instead.',
|
||||
);
|
||||
rerender(<Slider tooltipVisible />);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Slider] `tooltipVisible` is deprecated which will be removed in next major version, please use `tooltip.open` instead.',
|
||||
);
|
||||
rerender(<Slider tooltipPlacement="left" />);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Slider] `tooltipPlacement` is deprecated which will be removed in next major version, please use `tooltip.placement` instead.',
|
||||
);
|
||||
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
@ -7,17 +7,17 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
当 `tooltipVisible` 为 `true` 时,将始终显示 ToolTip;反之则始终不显示,即使在拖动、移入时也是如此。
|
||||
当 `tooltip.open` 为 `true` 时,将始终显示 ToolTip;反之则始终不显示,即使在拖动、移入时也是如此。
|
||||
|
||||
## en-US
|
||||
|
||||
When `tooltipVisible` is `true`, ToolTip will show always, or ToolTip will not show anyway, even if dragging or hovering.
|
||||
When `tooltip.open` is `true`, ToolTip will always show, or ToolTip will not show anyway, even if dragging or hovering.
|
||||
|
||||
```tsx
|
||||
import { Slider } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
const App: React.FC = () => <Slider defaultValue={30} tooltipVisible />;
|
||||
const App: React.FC = () => <Slider defaultValue={30} tooltip={{ open: true }} />;
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
@ -7,11 +7,11 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
使用 `tipFormatter` 可以格式化 `Tooltip` 的内容,设置 `tipFormatter={null}`,则隐藏 `Tooltip`。
|
||||
使用 `tooltip.formatter` 可以格式化 `Tooltip` 的内容,设置 `tooltip.formatter={null}`,则隐藏 `Tooltip`。
|
||||
|
||||
## en-US
|
||||
|
||||
Use `tipFormatter` to format content of `Tooltip`. If `tipFormatter` is null, hide it.
|
||||
Use `tooltip.formatter` to format content of `Tooltip`. If `tooltip.formatter` is null, hide it.
|
||||
|
||||
```tsx
|
||||
import { Slider } from 'antd';
|
||||
@ -21,8 +21,8 @@ const formatter = (value: number) => `${value}%`;
|
||||
|
||||
const App: React.FC = () => (
|
||||
<>
|
||||
<Slider tipFormatter={formatter} />
|
||||
<Slider tipFormatter={null} />
|
||||
<Slider tooltip={{ formatter }} />
|
||||
<Slider tooltip={{ formatter: null }} />
|
||||
</>
|
||||
);
|
||||
|
||||
|
@ -19,7 +19,6 @@ To input a value in a range.
|
||||
| defaultValue | The default value of slider. When `range` is false, use number, otherwise, use \[number, number] | number \| \[number, number] | 0 \| \[0, 0] | |
|
||||
| disabled | If true, the slider will not be interactable | boolean | false | |
|
||||
| dots | Whether the thumb can drag over tick only | boolean | false | |
|
||||
| getTooltipPopupContainer | The DOM container of the Tooltip, the default behavior is to create a div element in body | (triggerNode) => HTMLElement | () => document.body | |
|
||||
| included | Make effect when `marks` not null, true means containment and false means coordinative | boolean | true | |
|
||||
| marks | Tick mark of Slider, type of key must be `number`, and must in closed interval \[min, max], each mark can declare its own style | object | { number: ReactNode } \| { number: { style: CSSProperties, label: ReactNode } } | |
|
||||
| max | The maximum value the slider can slide to | number | 100 | |
|
||||
@ -27,9 +26,7 @@ To input a value in a range.
|
||||
| range | Dual thumb mode | boolean | false | |
|
||||
| reverse | Reverse the component | boolean | false | |
|
||||
| step | The granularity the slider can step through values. Must greater than 0, and be divided by (max - min) . When `marks` no null, `step` can be null | number \| null | 1 | |
|
||||
| tipFormatter | Slider will pass its value to `tipFormatter`, and display its value in Tooltip, and hide Tooltip when return value is null | value => ReactNode \| null | IDENTITY | |
|
||||
| tooltipPlacement | Set Tooltip display position. Ref [Tooltip](/components/tooltip/) | string | - | |
|
||||
| tooltipVisible | If true, Tooltip will show always, or it will not show anyway, even if dragging or hovering | boolean | - | |
|
||||
| tooltip | The tooltip relate props | [tooltip](#tooltip) | - | 4.23.0 |
|
||||
| value | The value of slider. When `range` is false, use number, otherwise, use \[number, number] | number \| \[number, number] | - | |
|
||||
| vertical | If true, the slider will be vertical | boolean | false | |
|
||||
| onAfterChange | Fire when onmouseup is fired | (value) => void | - | |
|
||||
@ -39,13 +36,22 @@ To input a value in a range.
|
||||
|
||||
### range
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| Property | Description | Type | Default | Version |
|
||||
| -------------- | ------------------------------- | ------- | ------- | ------- |
|
||||
| draggableTrack | Whether range track can be drag | boolean | false | 4.10.0 |
|
||||
|
||||
### tooltip
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| draggableTrack | Whether range track can be drag | boolean | false | 4.10.0 |
|
||||
| open | If true, Tooltip will show always, or it will not show anyway, even if dragging or hovering | boolean | - | 4.23.0 |
|
||||
| placement | Set Tooltip display position. Ref [Tooltip](/components/tooltip/) | string | - | 4.23.0 |
|
||||
| getPopupContainer | The DOM container of the Tooltip, the default behavior is to create a div element in body | (triggerNode) => HTMLElement | () => document.body | 4.23.0 |
|
||||
| formatter | Slider will pass its value to `formatter`, and display its value in Tooltip, and hide Tooltip when return value is null | value => ReactNode \| null | IDENTITY | 4.23.0 |
|
||||
|
||||
## Methods
|
||||
|
||||
| Name | Description | Version |
|
||||
| --- | --- | --- |
|
||||
| blur() | Remove focus | |
|
||||
| focus() | Get focus | |
|
||||
| Name | Description | Version |
|
||||
| ------- | ------------ | ------- |
|
||||
| blur() | Remove focus | |
|
||||
| focus() | Get focus | |
|
||||
|
@ -4,6 +4,7 @@ import RcSlider from 'rc-slider';
|
||||
import * as React from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import type { TooltipPlacement } from '../tooltip';
|
||||
import warning from '../_util/warning';
|
||||
import SliderTooltip from './SliderTooltip';
|
||||
|
||||
import useStyle from './style';
|
||||
@ -22,8 +23,20 @@ export type HandleGeneratorFn = (config: {
|
||||
info: HandleGeneratorInfo;
|
||||
}) => React.ReactElement;
|
||||
|
||||
export interface SliderTooltipProps {
|
||||
prefixCls?: string;
|
||||
open?: boolean;
|
||||
placement?: TooltipPlacement;
|
||||
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
||||
formatter?: null | ((value?: number) => React.ReactNode);
|
||||
}
|
||||
|
||||
export interface SliderBaseProps {
|
||||
prefixCls?: string;
|
||||
/**
|
||||
* @deprecated `tooltipPrefixCls` is deprecated which will be removed in next major version.
|
||||
* Please use `tooltip.prefixCls` instead.
|
||||
*/
|
||||
tooltipPrefixCls?: string;
|
||||
reverse?: boolean;
|
||||
min?: number;
|
||||
@ -34,12 +47,29 @@ export interface SliderBaseProps {
|
||||
included?: boolean;
|
||||
disabled?: boolean;
|
||||
vertical?: boolean;
|
||||
/**
|
||||
* @deprecated `tipFormatter` is deprecated which will be removed in next major version. Please
|
||||
* use `tooltip.formatter` instead.
|
||||
*/
|
||||
tipFormatter?: null | ((value?: number) => React.ReactNode);
|
||||
className?: string;
|
||||
id?: string;
|
||||
style?: React.CSSProperties;
|
||||
/**
|
||||
* @deprecated `tooltipVisible` is deprecated which will be removed in next major version. Please
|
||||
* use `tooltip.open` instead.
|
||||
*/
|
||||
tooltipVisible?: boolean;
|
||||
/**
|
||||
* @deprecated `tooltipPlacement` is deprecated which will be removed in next major version.
|
||||
* Please use `tooltip.placement` instead.
|
||||
*/
|
||||
tooltipPlacement?: TooltipPlacement;
|
||||
tooltip?: SliderTooltipProps;
|
||||
/**
|
||||
* @deprecated `getTooltipPopupContainer` is deprecated which will be removed in next major
|
||||
* version. Please use `tooltip.getPopupContainer` instead.
|
||||
*/
|
||||
getTooltipPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
||||
autoFocus?: boolean;
|
||||
}
|
||||
@ -68,15 +98,15 @@ interface SliderRange {
|
||||
draggableTrack?: boolean;
|
||||
}
|
||||
|
||||
export type Visibles = { [index: number]: boolean };
|
||||
export type Opens = { [index: number]: boolean };
|
||||
|
||||
const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
||||
(props, ref: any) => {
|
||||
const { getPrefixCls, direction, getPopupContainer } = React.useContext(ConfigContext);
|
||||
const [visibles, setVisibles] = React.useState<Visibles>({});
|
||||
const [opens, setOpens] = React.useState<Opens>({});
|
||||
|
||||
const toggleTooltipVisible = (index: number, visible: boolean) => {
|
||||
setVisibles((prev: Visibles) => ({ ...prev, [index]: visible }));
|
||||
const toggleTooltipOpen = (index: number, open: boolean) => {
|
||||
setOpens((prev: Opens) => ({ ...prev, [index]: open }));
|
||||
};
|
||||
|
||||
const getTooltipPlacement = (tooltipPlacement?: TooltipPlacement, vertical?: boolean) => {
|
||||
@ -89,15 +119,8 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
||||
return direction === 'rtl' ? 'left' : 'right';
|
||||
};
|
||||
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
tooltipPrefixCls: customizeTooltipPrefixCls,
|
||||
range,
|
||||
className,
|
||||
...restProps
|
||||
} = props;
|
||||
const { prefixCls: customizePrefixCls, range, className, ...restProps } = props;
|
||||
const prefixCls = getPrefixCls('slider', customizePrefixCls);
|
||||
const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
|
||||
@ -123,27 +146,66 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
||||
return typeof range === 'object' ? [true, range.draggableTrack] : [true, false];
|
||||
}, [range]);
|
||||
|
||||
// Warning for deprecated usage
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
[
|
||||
['tooltipPrefixCls', 'prefixCls'],
|
||||
['getTooltipPopupContainer', 'getPopupContainer'],
|
||||
['tipFormatter', 'formatter'],
|
||||
['tooltipPlacement', 'placement'],
|
||||
['tooltipVisible', 'open'],
|
||||
].forEach(([deprecatedName, newName]) => {
|
||||
warning(
|
||||
!(deprecatedName in props),
|
||||
'Slider',
|
||||
`\`${deprecatedName}\` is deprecated which will be removed in next major version, please use \`tooltip.${newName}\` instead.`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const handleRender: RcSliderProps['handleRender'] = (node, info) => {
|
||||
const { index, dragging } = info;
|
||||
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
const { tipFormatter, tooltipVisible, tooltipPlacement, getTooltipPopupContainer, vertical } =
|
||||
props;
|
||||
const { tooltip = {}, vertical } = props;
|
||||
|
||||
const isTipFormatter = tipFormatter ? visibles[index] || dragging : false;
|
||||
const visible = tooltipVisible || (tooltipVisible === undefined && isTipFormatter);
|
||||
const tooltipProps: SliderTooltipProps = {
|
||||
formatter:
|
||||
props.tipFormatter ??
|
||||
// eslint-disable-next-line func-names
|
||||
function (value) {
|
||||
return typeof value === 'number' ? value.toString() : '';
|
||||
},
|
||||
open: props.tooltipVisible,
|
||||
placement: props.tooltipPlacement,
|
||||
getPopupContainer: props.getTooltipPopupContainer,
|
||||
...tooltip,
|
||||
};
|
||||
|
||||
const {
|
||||
open: tooltipOpen,
|
||||
placement: tooltipPlacement,
|
||||
getPopupContainer: getTooltipPopupContainer,
|
||||
prefixCls: customizeTooltipPrefixCls,
|
||||
formatter: tipFormatter,
|
||||
} = tooltipProps;
|
||||
|
||||
const isTipFormatter = tipFormatter ? opens[index] || dragging : false;
|
||||
const open = tooltipOpen || (tooltipOpen === undefined && isTipFormatter);
|
||||
|
||||
const passedProps = {
|
||||
...node.props,
|
||||
onMouseEnter: () => toggleTooltipVisible(index, true),
|
||||
onMouseLeave: () => toggleTooltipVisible(index, false),
|
||||
onMouseEnter: () => toggleTooltipOpen(index, true),
|
||||
onMouseLeave: () => toggleTooltipOpen(index, false),
|
||||
};
|
||||
|
||||
const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls);
|
||||
|
||||
return (
|
||||
<SliderTooltip
|
||||
prefixCls={tooltipPrefixCls}
|
||||
title={tipFormatter ? tipFormatter(info.value) : ''}
|
||||
visible={visible}
|
||||
visible={open}
|
||||
placement={getTooltipPlacement(tooltipPlacement, vertical)}
|
||||
transitionName={`${rootPrefixCls}-zoom-down`}
|
||||
key={index}
|
||||
@ -174,10 +236,4 @@ if (process.env.NODE_ENV !== 'production') {
|
||||
Slider.displayName = 'Slider';
|
||||
}
|
||||
|
||||
Slider.defaultProps = {
|
||||
tipFormatter(value: number) {
|
||||
return typeof value === 'number' ? value.toString() : '';
|
||||
},
|
||||
};
|
||||
|
||||
export default Slider;
|
||||
|
@ -28,9 +28,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/HZ3meFc6W/Silder.svg
|
||||
| range | 双滑块模式 | boolean \| [range](#range) | false | |
|
||||
| reverse | 反向坐标轴 | boolean | false | |
|
||||
| step | 步长,取值必须大于 0,并且可被 (max - min) 整除。当 `marks` 不为空对象时,可以设置 `step` 为 null,此时 Slider 的可选值仅有 marks 标出来的部分 | number \| null | 1 | |
|
||||
| tipFormatter | Slider 会把当前值传给 `tipFormatter`,并在 Tooltip 中显示 `tipFormatter` 的返回值,若为 null,则隐藏 Tooltip | value => ReactNode \| null | IDENTITY | |
|
||||
| tooltipPlacement | 设置 Tooltip 展示位置。参考 [Tooltip](/components/tooltip/) | string | - | |
|
||||
| tooltipVisible | 值为 true 时,Tooltip 将会始终显示;否则始终不显示,哪怕在拖拽及移入时 | boolean | - | |
|
||||
| tooltip | 设置 Tooltip 相关属性 | [tooltip](#tooltip) | - | 4.23.0 |
|
||||
| value | 设置当前取值。当 `range` 为 false 时,使用 number,否则用 \[number, number] | number \| \[number, number] | - | |
|
||||
| vertical | 值为 true 时,Slider 为垂直方向 | boolean | false | |
|
||||
| onAfterChange | 与 `onmouseup` 触发时机一致,把当前值作为参数传入 | (value) => void | - | |
|
||||
@ -38,13 +36,22 @@ cover: https://gw.alipayobjects.com/zos/alicdn/HZ3meFc6W/Silder.svg
|
||||
|
||||
### range
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| -------------- | -------------------- | ------- | ------ | ------ |
|
||||
| draggableTrack | 范围刻度是否可被拖拽 | boolean | false | 4.10.0 |
|
||||
|
||||
### tooltip
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| draggableTrack | 范围刻度是否可被拖拽 | boolean | false | 4.10.0 |
|
||||
| open | 值为 true 时,Tooltip 将会始终显示;否则始终不显示,哪怕在拖拽及移入时 | boolean | - | 4.23.0 |
|
||||
| placement | 设置 Tooltip 展示位置。参考 [Tooltip](/components/tooltip/) | string | - | 4.23.0 |
|
||||
| getPopupContainer | Tooltip 渲染父节点,默认渲染到 body 上 | (triggerNode) => HTMLElement | () => document.body | 4.23.0 |
|
||||
| formatter | Slider 会把当前值传给 `formatter`,并在 Tooltip 中显示 `formatter` 的返回值,若为 null,则隐藏 Tooltip | value => ReactNode \| null | IDENTITY | 4.23.0 |
|
||||
|
||||
## 方法
|
||||
|
||||
| 名称 | 描述 | 版本 |
|
||||
| --- | --- | --- |
|
||||
| blur() | 移除焦点 | |
|
||||
| focus() | 获取焦点 | |
|
||||
| 名称 | 描述 | 版本 |
|
||||
| ------- | -------- | ---- |
|
||||
| blur() | 移除焦点 | |
|
||||
| focus() | 获取焦点 | |
|
||||
|
@ -33,6 +33,7 @@ function renderExpandIcon(locale: TableLocale) {
|
||||
[`${iconPrefix}-collapsed`]: expandable && !expanded,
|
||||
})}
|
||||
aria-label={expanded ? locale.collapse : locale.expand}
|
||||
aria-expanded={expanded}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ interface ChangeEventInfo<RecordType> {
|
||||
total?: number;
|
||||
};
|
||||
filters: Record<string, FilterValue | null>;
|
||||
sorter: SorterResult<RecordType> | SorterResult<RecordType[]>;
|
||||
sorter: SorterResult<RecordType> | SorterResult<RecordType>[];
|
||||
|
||||
filterStates: FilterState<RecordType>[];
|
||||
sorterStates: SortState<RecordType>[];
|
||||
@ -94,7 +94,7 @@ export interface TableProps<RecordType>
|
||||
onChange?: (
|
||||
pagination: TablePaginationConfig,
|
||||
filters: Record<string, FilterValue | null>,
|
||||
sorter: SorterResult<RecordType> | SorterResult<RecordType[]>,
|
||||
sorter: SorterResult<RecordType> | SorterResult<RecordType>[],
|
||||
extra: TableCurrentDataSource<RecordType>,
|
||||
) => void;
|
||||
rowSelection?: TableRowSelection<RecordType>;
|
||||
@ -265,7 +265,7 @@ function InternalTable<RecordType extends object = any>(
|
||||
|
||||
// ============================ Sorter =============================
|
||||
const onSorterChange = (
|
||||
sorter: SorterResult<RecordType> | SorterResult<RecordType[]>,
|
||||
sorter: SorterResult<RecordType> | SorterResult<RecordType>[],
|
||||
sorterStates: SortState<RecordType>[],
|
||||
) => {
|
||||
triggerOnChange(
|
||||
|
@ -82,6 +82,13 @@ describe('Table.expand', () => {
|
||||
expect(container.querySelector('.indent-level-1').style.paddingLeft).toEqual('0px');
|
||||
});
|
||||
|
||||
it('has right aria-expanded state', () => {
|
||||
const { container } = render(<Table columns={columns} dataSource={data} />);
|
||||
expect(container.querySelector('[aria-expanded=false]')).toBeTruthy();
|
||||
fireEvent.click(container.querySelector('.ant-table-row-expand-icon'));
|
||||
expect(container.querySelector('[aria-expanded=true]')).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('expandIconColumnIndex', () => {
|
||||
it('basic', () => {
|
||||
const { container } = render(
|
||||
|
@ -992,4 +992,104 @@ describe('Table.sorter', () => {
|
||||
clickToMatchExpect(1, { field: 'english', order: 'descend' });
|
||||
clickToMatchExpect(1, { field: 'english', order: undefined });
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/37024
|
||||
it('multiple sort should pass array sorter as onChange param', () => {
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: 'Chinese Score',
|
||||
dataIndex: 'chinese',
|
||||
sorter: {
|
||||
compare: (a, b) => a.chinese - b.chinese,
|
||||
multiple: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Math Score',
|
||||
dataIndex: 'math',
|
||||
sorter: {
|
||||
compare: (a, b) => a.math - b.math,
|
||||
multiple: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'English Score',
|
||||
dataIndex: 'english',
|
||||
sorter: {
|
||||
compare: (a, b) => a.english - b.english,
|
||||
multiple: 1,
|
||||
},
|
||||
},
|
||||
];
|
||||
const tableData = [
|
||||
{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
chinese: 98,
|
||||
math: 60,
|
||||
english: 70,
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: 'Jim Green',
|
||||
chinese: 98,
|
||||
math: 66,
|
||||
english: 89,
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: 'Joe Black',
|
||||
chinese: 98,
|
||||
math: 90,
|
||||
english: 70,
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
name: 'Jim Red',
|
||||
chinese: 88,
|
||||
math: 99,
|
||||
english: 89,
|
||||
},
|
||||
];
|
||||
|
||||
const onChange = jest.fn();
|
||||
|
||||
const { container } = render(
|
||||
<Table columns={columns} dataSource={tableData} onChange={onChange} />,
|
||||
);
|
||||
const sorterColumns = Array.from(container.querySelectorAll('.ant-table-column-has-sorters'));
|
||||
expect(sorterColumns.length).toBe(3);
|
||||
fireEvent.click(sorterColumns[0]);
|
||||
expect(onChange).toHaveBeenLastCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
expect.objectContaining({ field: 'chinese' }),
|
||||
expect.anything(),
|
||||
);
|
||||
fireEvent.click(sorterColumns[1]);
|
||||
expect(onChange).toHaveBeenLastCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ field: 'chinese' }),
|
||||
expect.objectContaining({ field: 'math' }),
|
||||
]),
|
||||
expect.anything(),
|
||||
);
|
||||
fireEvent.click(sorterColumns[2]);
|
||||
expect(onChange).toHaveBeenLastCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ field: 'chinese' }),
|
||||
expect.objectContaining({ field: 'math' }),
|
||||
expect.objectContaining({ field: 'english' }),
|
||||
]),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -49,6 +49,7 @@ exports[`Table.expand click to expand 1`] = `
|
||||
style="padding-left: 0px;"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -67,6 +68,7 @@ exports[`Table.expand click to expand 1`] = `
|
||||
style="padding-left: 15px;"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
|
@ -116,6 +116,7 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
|
||||
style="position: sticky; left: 0px;"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -157,6 +158,7 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
|
||||
style="position: sticky; left: 0px;"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -198,6 +200,7 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
|
||||
style="position: sticky; left: 0px;"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -239,6 +242,7 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
|
||||
style="position: sticky; left: 0px;"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
|
@ -3671,6 +3671,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3774,6 +3775,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3877,6 +3879,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3980,6 +3983,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -4083,6 +4087,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -4186,6 +4191,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -4289,6 +4295,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -4392,6 +4399,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -4495,6 +4503,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -4598,6 +4607,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -6816,6 +6826,7 @@ exports[`renders ./components/table/demo/expand.md extend context correctly 1`]
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -6852,6 +6863,7 @@ exports[`renders ./components/table/demo/expand.md extend context correctly 1`]
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -6888,6 +6900,7 @@ exports[`renders ./components/table/demo/expand.md extend context correctly 1`]
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -6924,6 +6937,7 @@ exports[`renders ./components/table/demo/expand.md extend context correctly 1`]
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -15951,6 +15965,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -16002,6 +16017,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -16053,6 +16069,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -16275,6 +16292,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -17053,6 +17071,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -17104,6 +17123,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -17316,6 +17336,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -18094,6 +18115,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -18145,6 +18167,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -18357,6 +18380,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -19135,6 +19159,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -19186,6 +19211,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -19415,6 +19441,7 @@ exports[`renders ./components/table/demo/order-column.md extend context correctl
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -19463,6 +19490,7 @@ exports[`renders ./components/table/demo/order-column.md extend context correctl
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -19511,6 +19539,7 @@ exports[`renders ./components/table/demo/order-column.md extend context correctl
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -19559,6 +19588,7 @@ exports[`renders ./components/table/demo/order-column.md extend context correctl
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -26480,6 +26510,7 @@ Array [
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -26528,6 +26559,7 @@ Array [
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -26787,6 +26819,7 @@ Array [
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -26842,6 +26875,7 @@ Array [
|
||||
style="padding-left:15px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -26897,6 +26931,7 @@ Array [
|
||||
style="padding-left:15px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -26952,6 +26987,7 @@ Array [
|
||||
style="padding-left:30px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -27007,6 +27043,7 @@ Array [
|
||||
style="padding-left:15px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -27062,6 +27099,7 @@ Array [
|
||||
style="padding-left:30px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -27117,6 +27155,7 @@ Array [
|
||||
style="padding-left:45px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -27172,6 +27211,7 @@ Array [
|
||||
style="padding-left:45px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -27227,6 +27267,7 @@ Array [
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
|
@ -2944,6 +2944,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3047,6 +3048,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3150,6 +3152,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3253,6 +3256,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3356,6 +3360,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3459,6 +3464,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3562,6 +3568,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3665,6 +3672,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3768,6 +3776,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -3871,6 +3880,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -5535,6 +5545,7 @@ exports[`renders ./components/table/demo/expand.md correctly 1`] = `
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -5571,6 +5582,7 @@ exports[`renders ./components/table/demo/expand.md correctly 1`] = `
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -5607,6 +5619,7 @@ exports[`renders ./components/table/demo/expand.md correctly 1`] = `
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -5643,6 +5656,7 @@ exports[`renders ./components/table/demo/expand.md correctly 1`] = `
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -12173,6 +12187,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -12224,6 +12239,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -12275,6 +12291,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -12497,6 +12514,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -12888,6 +12906,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -12939,6 +12958,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -13151,6 +13171,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -13542,6 +13563,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -13593,6 +13615,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -13805,6 +13828,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -14196,6 +14220,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -14247,6 +14272,7 @@ Array [
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -14476,6 +14502,7 @@ exports[`renders ./components/table/demo/order-column.md correctly 1`] = `
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -14524,6 +14551,7 @@ exports[`renders ./components/table/demo/order-column.md correctly 1`] = `
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -14572,6 +14600,7 @@ exports[`renders ./components/table/demo/order-column.md correctly 1`] = `
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -14620,6 +14649,7 @@ exports[`renders ./components/table/demo/order-column.md correctly 1`] = `
|
||||
class="ant-table-cell ant-table-row-expand-icon-cell"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -20659,6 +20689,7 @@ Array [
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
@ -20707,6 +20738,7 @@ Array [
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -20966,6 +20998,7 @@ Array [
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -21021,6 +21054,7 @@ Array [
|
||||
style="padding-left:15px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -21076,6 +21110,7 @@ Array [
|
||||
style="padding-left:15px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -21131,6 +21166,7 @@ Array [
|
||||
style="padding-left:30px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -21186,6 +21222,7 @@ Array [
|
||||
style="padding-left:15px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -21241,6 +21278,7 @@ Array [
|
||||
style="padding-left:30px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-expanded"
|
||||
type="button"
|
||||
@ -21296,6 +21334,7 @@ Array [
|
||||
style="padding-left:45px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -21351,6 +21390,7 @@ Array [
|
||||
style="padding-left:45px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
@ -21406,6 +21446,7 @@ Array [
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
aria-label="Collapse row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
|
@ -36,12 +36,6 @@ describe('Table.typescript', () => {
|
||||
const table = <Table<RecordType> dataSource={[{ key: 'Bamboo' }]} />;
|
||||
expect(table).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Sorter types', () => {
|
||||
const table = <Table onChange={(_pagination, _filters, sorter) => sorter.field} />;
|
||||
|
||||
expect(table).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Table.typescript types', () => {
|
||||
|
@ -247,7 +247,7 @@ function stateToInfo<RecordType>(sorterStates: SortState<RecordType>) {
|
||||
|
||||
function generateSorterInfo<RecordType>(
|
||||
sorterStates: SortState<RecordType>[],
|
||||
): SorterResult<RecordType> | SorterResult<RecordType[]> {
|
||||
): SorterResult<RecordType> | SorterResult<RecordType>[] {
|
||||
const list = sorterStates.filter(({ sortOrder }) => sortOrder).map(stateToInfo);
|
||||
|
||||
// =========== Legacy compatible support ===========
|
||||
@ -259,7 +259,11 @@ function generateSorterInfo<RecordType>(
|
||||
};
|
||||
}
|
||||
|
||||
return list[0] || {};
|
||||
if (list.length <= 1) {
|
||||
return list[0] || {};
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
export function getSortData<RecordType>(
|
||||
@ -320,7 +324,7 @@ interface SorterConfig<RecordType> {
|
||||
prefixCls: string;
|
||||
mergedColumns: ColumnsType<RecordType>;
|
||||
onSorterChange: (
|
||||
sorterResult: SorterResult<RecordType> | SorterResult<RecordType[]>,
|
||||
sorterResult: SorterResult<RecordType> | SorterResult<RecordType>[],
|
||||
sortStates: SortState<RecordType>[],
|
||||
) => void;
|
||||
sortDirections: SortOrder[];
|
||||
@ -339,7 +343,7 @@ export default function useFilterSorter<RecordType>({
|
||||
TransformColumns<RecordType>,
|
||||
SortState<RecordType>[],
|
||||
ColumnTitleProps<RecordType>,
|
||||
() => SorterResult<RecordType> | SorterResult<RecordType[]>,
|
||||
() => SorterResult<RecordType> | SorterResult<RecordType>[],
|
||||
] {
|
||||
const [sortStates, setSortStates] = React.useState<SortState<RecordType>[]>(
|
||||
collectSortStates(mergedColumns, true),
|
||||
|
@ -1,12 +1,12 @@
|
||||
import dayjs from 'dayjs';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
import { mount } from 'enzyme';
|
||||
import React from 'react';
|
||||
import TimePicker from '..';
|
||||
import focusTest from '../../../tests/shared/focusTest';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { resetWarned } from '../../_util/warning';
|
||||
import { render } from '../../../tests/utils';
|
||||
|
||||
dayjs.extend(customParseFormat);
|
||||
|
||||
@ -32,83 +32,84 @@ describe('TimePicker', () => {
|
||||
OK
|
||||
</button>
|
||||
);
|
||||
const wrapper = mount(<TimePicker addon={addon} open />);
|
||||
|
||||
expect(wrapper.find('.my-btn').length).toBeTruthy();
|
||||
const { container } = render(<TimePicker addon={addon} open />);
|
||||
expect(container.querySelectorAll('.my-btn').length).toBeTruthy();
|
||||
expect(errorSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: TimePicker] `addon` is deprecated. Please use `renderExtraFooter` instead.',
|
||||
);
|
||||
});
|
||||
|
||||
it('not render clean icon when allowClear is false', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<TimePicker defaultValue={dayjs('2000-01-01 00:00:00')} allowClear={false} />,
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('clearIcon should render correctly', () => {
|
||||
const clearIcon = <div className="test-clear-icon">test</div>;
|
||||
const wrapper = mount(<TimePicker clearIcon={clearIcon} />);
|
||||
expect(wrapper.find('Picker').last().prop('clearIcon')).toEqual(
|
||||
<div className="test-clear-icon">test</div>,
|
||||
const { container } = render(
|
||||
<TimePicker clearIcon={clearIcon} value={dayjs('00:00:00', 'HH:mm:ss')} />,
|
||||
);
|
||||
expect(container.querySelector('.test-clear-icon')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('prop locale should works', () => {
|
||||
const locale = {
|
||||
placeholder: 'Избери дата',
|
||||
};
|
||||
const wrapper = mount(
|
||||
<TimePicker defaultValue={dayjs('2000-01-01 00:00:00')} open locale={locale} />,
|
||||
const { container } = render(
|
||||
<TimePicker defaultValue={dayjs('2000-01-01 00:00:00')} open locale={locale as any} />,
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(Array.from(container.children)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should pass popupClassName prop to Picker as dropdownClassName prop', () => {
|
||||
const popupClassName = 'myCustomClassName';
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<TimePicker
|
||||
open
|
||||
defaultOpenValue={dayjs('00:00:00', 'HH:mm:ss')}
|
||||
popupClassName={popupClassName}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find('Picker').last().prop('dropdownClassName')).toEqual(popupClassName);
|
||||
expect(container.querySelector(`.${popupClassName}`)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should pass popupClassName prop to RangePicker as dropdownClassName prop', () => {
|
||||
const popupClassName = 'myCustomClassName';
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<TimePicker.RangePicker
|
||||
open
|
||||
defaultOpenValue={dayjs('00:00:00', 'HH:mm:ss')}
|
||||
popupClassName={popupClassName}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.find('RangePicker').last().prop('dropdownClassName')).toEqual(popupClassName);
|
||||
expect(container.querySelector(`.${popupClassName}`)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('RangePicker should show warning when use dropdownClassName', () => {
|
||||
mount(<TimePicker.RangePicker dropdownClassName="myCustomClassName" />);
|
||||
render(<TimePicker.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('TimePicker should show warning when use dropdownClassName', () => {
|
||||
mount(<TimePicker dropdownClassName="myCustomClassName" />);
|
||||
render(<TimePicker dropdownClassName="myCustomClassName" />);
|
||||
expect(errorSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: TimePicker] `dropdownClassName` is deprecated which will be removed in next major version. Please use `popupClassName` instead.',
|
||||
);
|
||||
});
|
||||
|
||||
it('should support bordered', () => {
|
||||
const wrapper = mount(
|
||||
const { container } = render(
|
||||
<TimePicker
|
||||
className="custom-class"
|
||||
defaultValue={dayjs('2000-01-01 00:00:00')}
|
||||
bordered={false}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
@ -17,7 +17,11 @@ Please find below some of the design resources and tools about Ant Design that w
|
||||
- Sketch Symbols
|
||||
- https://gw.alipayobjects.com/zos/basement_prod/048ee28f-2c80-4d15-9aa3-4f5ddac50465.svg
|
||||
- Sketch Symbols for Desktop
|
||||
- https://github.com/ant-design/ant-design/files/2051729/Ant.Design.Template.sketch.zip
|
||||
- https://gw.alipayobjects.com/os/bmw-prod/a5ff1d86-44cd-4b86-92f8-daab59cba5b7.sketch
|
||||
- Sketch Symbols (Dark)
|
||||
- https://gw.alipayobjects.com/zos/basement_prod/048ee28f-2c80-4d15-9aa3-4f5ddac50465.svg
|
||||
- Sketch Symbols for Desktop with dark theme
|
||||
- https://gw.alipayobjects.com/os/bmw-prod/6b670a1c-26e3-4379-9c86-7a2b95e170e5.sketch
|
||||
- Mobile Components
|
||||
- https://gw.alipayobjects.com/zos/basement_prod/c0c3852c-d245-4330-886b-cb02ef49eb6d.svg
|
||||
- Sketch Symbols File for Mobile
|
||||
|
@ -17,7 +17,11 @@ toc: false
|
||||
- Sketch 组件包
|
||||
- https://gw.alipayobjects.com/zos/basement_prod/048ee28f-2c80-4d15-9aa3-4f5ddac50465.svg
|
||||
- 桌面组件 Sketch 模板包
|
||||
- https://gw.alipayobjects.com/os/antfincdn/EfSt1N5LCk/Ant.Design.Components.4.0.zip
|
||||
- https://gw.alipayobjects.com/os/bmw-prod/82c08c51-9993-4568-90c1-249c8301c0af.sketch
|
||||
- Sketch 组件包 (暗色)
|
||||
- https://gw.alipayobjects.com/zos/basement_prod/048ee28f-2c80-4d15-9aa3-4f5ddac50465.svg
|
||||
- 桌面组件 Sketch 模板包,内含暗色版本的 antd 组件
|
||||
- https://gw.alipayobjects.com/os/bmw-prod/f002145c-33d9-408e-ba75-a1a68896dfa3.sketch
|
||||
- Mobile Components
|
||||
- https://gw.alipayobjects.com/zos/basement_prod/c0c3852c-d245-4330-886b-cb02ef49eb6d.svg
|
||||
- 移动组件 Sketch 模板
|
||||
|
@ -131,7 +131,7 @@
|
||||
"rc-input": "~0.1.2",
|
||||
"rc-input-number": "~7.3.5",
|
||||
"rc-mentions": "~1.9.1",
|
||||
"rc-menu": "~9.6.0",
|
||||
"rc-menu": "~9.6.3",
|
||||
"rc-motion": "^2.6.1",
|
||||
"rc-notification": "~5.0.0-alpha.9",
|
||||
"rc-pagination": "~3.1.17",
|
||||
|
@ -9,6 +9,11 @@ const packageJson = require('../package.json');
|
||||
|
||||
const DEPRECIATED_VERSION = {
|
||||
'>= 4.21.6 < 4.22.0': ['https://github.com/ant-design/ant-design/pull/36682'],
|
||||
'>=4.22.2 <=4.22.5': [
|
||||
'https://github.com/ant-design/ant-design/issues/36932',
|
||||
'https://github.com/ant-design/ant-design/pull/36800',
|
||||
'https://github.com/ant-design/ant-design/issues/37024',
|
||||
],
|
||||
};
|
||||
|
||||
function matchDeprecated(version) {
|
||||
@ -89,7 +94,12 @@ const SAFE_DAYS_DIFF = 1000 * 60 * 60 * 24 * 3; // 3 days not update seems to be
|
||||
|
||||
// Not find to use the latest version instead
|
||||
defaultVersionObj = defaultVersionObj || defaultVersionList[defaultVersionList.length - 1];
|
||||
const defaultVersion = defaultVersionObj ? defaultVersionObj.value : null;
|
||||
let defaultVersion = defaultVersionObj ? defaultVersionObj.value : null;
|
||||
|
||||
// If default version is less than current, use current
|
||||
if (semver.compare(defaultVersion, distTags.conch) < 0) {
|
||||
defaultVersion = distTags.conch;
|
||||
}
|
||||
|
||||
// Selection
|
||||
let { conchVersion } = await inquirer.prompt([
|
||||
@ -102,11 +112,24 @@ const SAFE_DAYS_DIFF = 1000 * 60 * 60 * 24 * 3; // 3 days not update seems to be
|
||||
const { value, publishTime, depreciated } = info;
|
||||
const desc = dayjs(publishTime).fromNow();
|
||||
|
||||
//
|
||||
|
||||
return {
|
||||
...info,
|
||||
name: `${depreciated ? '🚨' : '✅'} ${value} (${desc}) ${
|
||||
value === defaultVersion ? '(default)' : ''
|
||||
}`,
|
||||
name: [
|
||||
// Warning
|
||||
depreciated ? '🚨' : '✅',
|
||||
// Version
|
||||
value,
|
||||
// Date Diff
|
||||
`(${desc})`,
|
||||
// Default Mark
|
||||
value === defaultVersion ? '(default)' : '',
|
||||
// Current Mark
|
||||
value === distTags.conch ? chalk.gray('- current') : '',
|
||||
]
|
||||
.filter(str => String(str).trim())
|
||||
.join(' '),
|
||||
};
|
||||
}),
|
||||
},
|
||||
|
@ -17,6 +17,8 @@
|
||||
}
|
||||
|
||||
html {
|
||||
direction: initial;
|
||||
|
||||
&.rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import './Navigation.less';
|
||||
|
||||
export interface NavigationProps extends SharedProps {
|
||||
isMobile: boolean;
|
||||
isRTL: boolean;
|
||||
pathname: string;
|
||||
responsive: null | 'narrow' | 'crowded';
|
||||
location: { pathname: string; query: any };
|
||||
|
@ -186,7 +186,7 @@ const Header: React.FC<HeaderProps & WrappedComponentProps<'intl'>> = props => {
|
||||
);
|
||||
}, [location]);
|
||||
|
||||
const getNextDirectionText = useMemo<string>(
|
||||
const nextDirectionText = useMemo<string>(
|
||||
() => (direction !== 'rtl' ? 'RTL' : 'LTR'),
|
||||
[direction],
|
||||
);
|
||||
@ -242,7 +242,7 @@ const Header: React.FC<HeaderProps & WrappedComponentProps<'intl'>> = props => {
|
||||
isMobile={isMobile}
|
||||
showTechUIButton={showTechUIButton}
|
||||
pathname={pathname}
|
||||
directionText={getNextDirectionText}
|
||||
directionText={nextDirectionText}
|
||||
onLangChange={onLangChange}
|
||||
onDirectionChange={onDirectionChange}
|
||||
/>
|
||||
@ -275,7 +275,7 @@ const Header: React.FC<HeaderProps & WrappedComponentProps<'intl'>> = props => {
|
||||
className="header-button header-direction-button"
|
||||
key="direction-button"
|
||||
>
|
||||
{getNextDirectionText}
|
||||
{nextDirectionText}
|
||||
</Button>,
|
||||
<More key="more" {...sharedProps} />,
|
||||
<Github key="github" responsive={responsive} />,
|
||||
|
@ -270,6 +270,7 @@ export default class Layout extends React.Component<LayoutPropsType, LayoutState
|
||||
appLocale.locale === 'zh-CN'
|
||||
? '基于 Ant Design 设计体系的 React UI 组件库,用于研发企业级中后台产品。'
|
||||
: 'An enterprise-class UI design language and React UI library with a set of high-quality React components, one of best React UI library for enterprises';
|
||||
|
||||
return (
|
||||
<StyleProvider cache={styleCache}>
|
||||
{/* eslint-disable-next-line react/jsx-no-constructed-context-values */}
|
||||
|
Loading…
Reference in New Issue
Block a user