chore: auto merge branchs (#35347)

chore: Feature merge master
This commit is contained in:
github-actions[bot] 2022-05-01 10:16:06 +00:00 committed by GitHub
commit 85707ff36f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 3489 additions and 2319 deletions

4
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,4 @@
package.json @ant-design/ant-design-core
.github/workflows/ @ant-design/ant-design-core
scripts/ @ant-design/ant-design-core
LICENSE @ant-design/ant-design-core

View File

@ -22,7 +22,7 @@ jobs:
assignees: 'afc163, zombieJ, xrkffgg, MadCcc'
comment-mark: 'version'
comment: |
Hi @${{ github.event.pull_request.user.login }}. Thanks for your contribution. The path `.github/` or `scripts/` and `CHANGELOG` `package.json` is only maintained by team members. This current PR will be closed and team members will help on this.
Hi @${{ github.event.pull_request.user.login }}. Thanks for your contribution. The path `.github/` or `scripts/` and `CHANGELOG` is only maintained by team members. This current PR will be closed and team members will help on this.
close: true
set-failed: false

View File

@ -15,6 +15,22 @@ timeline: true
---
## 4.20.2
`2022-04-30`
- Segmented
- 🐞 Fix Segmented inconsisit height with other controls. [#35281](https://github.com/ant-design/ant-design/pull/35281)
- 🐞 Fix Segmented animation not working correct in StrictMode mode. [#35281](https://github.com/ant-design/ant-design/pull/35281)
- 🆕 Segmented `options` now supports `icon` property. [#35256](https://github.com/ant-design/ant-design/pull/35256)
- Table
- ⌨️ Improve Table columns sorter a11y experience. [#35269](https://github.com/ant-design/ant-design/pull/35269)
- 🇪🇸 Added Table filter localization for es_ES. [#35309](https://github.com/ant-design/ant-design/pull/35309) [@agarciaguillo](https://github.com/agarciaguillo)
- 💄 Fix Switch color in dark theme. [#35332](https://github.com/ant-design/ant-design/pull/35332)
- 💄 Tweak Breadcrumb link hover color. [#35324](https://github.com/ant-design/ant-design/pull/35324)
- 🐞 Fix Space throws `Encountered two children with the same key` warning in some cases. [#35311](https://github.com/ant-design/ant-design/pull/35311)
- 🐞 Fix Select tag remove icon position issue. [#35336](https://github.com/ant-design/ant-design/pull/35336) [@walidcherhane](https://github.com/walidcherhane)
## 4.20.1
`2022-04-26`

View File

@ -15,6 +15,22 @@ timeline: true
---
## 4.20.2
`2022-04-30`
- Segmented
- 🐞 修复 Segmented 组件高度和其他控件不一致的问题。[#35281](https://github.com/ant-design/ant-design/pull/35281)
- 🐞 修复 React StrictMode 下 Segmented 动画丢失的问题。[#35281](https://github.com/ant-design/ant-design/pull/35281)
- 🆕 Segmented `options` 支持设置 `icon` 属性。[#35256](https://github.com/ant-design/ant-design/pull/35256)
- Table
- ⌨️ 优化 Table 排序按钮的键盘可访问性。[#35269](https://github.com/ant-design/ant-design/pull/35269)
- 🇪🇸 补充 Table 西班牙语筛选文案。[#35309](https://github.com/ant-design/ant-design/pull/35309) [@agarciaguillo](https://github.com/agarciaguillo)
- 🐞 修复 Switch 在暗黑主题下关闭时的颜色问题。[#35332](https://github.com/ant-design/ant-design/pull/35332)
- 💄 微调 Breadcrumb 链接 hover 色为中性色。[#35324](https://github.com/ant-design/ant-design/pull/35324)
- 🐞 修复 Space 在某些情况下抛出 `Encountered two children with the same key` 警告的问题。[#35311](https://github.com/ant-design/ant-design/pull/35311)
- 🐞 修复 Select 多选标签移除图标位置偏下的问题。[#35336](https://github.com/ant-design/ant-design/pull/35336) [@walidcherhane](https://github.com/walidcherhane)
## 4.20.1
`2022-04-26`

View File

@ -10,6 +10,7 @@ import Group from '../../radio/group';
import Button from '../../radio/radioButton';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { render, fireEvent } from '../../../tests/utils';
describe('Calendar', () => {
mountTest(Calendar);
@ -40,14 +41,21 @@ describe('Calendar', () => {
});
it('Calendar should be selectable', () => {
MockDate.set(Moment('2000-01-01').valueOf());
const onSelect = jest.fn();
const onChange = jest.fn();
const wrapper = mount(<Calendar onSelect={onSelect} onChange={onChange} />);
wrapper.find('.ant-picker-cell').at(0).simulate('click');
const { container } = render(<Calendar onSelect={onSelect} onChange={onChange} />);
fireEvent.click(container.querySelector('.ant-picker-cell'));
expect(onSelect).toHaveBeenCalledWith(expect.anything());
const value = onSelect.mock.calls[0][0];
expect(Moment.isMoment(value)).toBe(true);
expect(onChange).toHaveBeenCalled();
MockDate.reset();
});
it('only Valid range should be selectable', () => {

View File

@ -139,6 +139,8 @@ function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
};
const triggerChange = (date: DateType) => {
console.log('trigger change!!!', isSameDate(date, mergedValue));
console.log('trigger change!!!', String(date), String(mergedValue));
setMergedValue(date);
if (!isSameDate(date, mergedValue)) {

View File

@ -22867,6 +22867,7 @@ exports[`ConfigProvider components Table configProvider 1`] = `
<tr>
<th
class="config-table-cell config-table-column-has-sorters"
tabindex="0"
>
<div
class="config-table-filter-column"
@ -23147,6 +23148,7 @@ exports[`ConfigProvider components Table configProvider componentSize large 1`]
<tr>
<th
class="config-table-cell config-table-column-has-sorters"
tabindex="0"
>
<div
class="config-table-filter-column"
@ -23427,6 +23429,7 @@ exports[`ConfigProvider components Table configProvider componentSize middle 1`]
<tr>
<th
class="config-table-cell config-table-column-has-sorters"
tabindex="0"
>
<div
class="config-table-filter-column"
@ -23707,6 +23710,7 @@ exports[`ConfigProvider components Table configProvider virtual and dropdownMatc
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -23987,6 +23991,7 @@ exports[`ConfigProvider components Table normal 1`] = `
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -24267,6 +24272,7 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
<tr>
<th
class="prefix-Table-cell prefix-Table-column-has-sorters"
tabindex="0"
>
<div
class="prefix-Table-filter-column"

View File

@ -1,7 +1,7 @@
import React from 'react';
import { mount } from 'enzyme';
import Empty from '..';
import ConfigProvider from '../../config-provider';
import { render } from '../../../tests/utils';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
@ -10,21 +10,21 @@ describe('Empty', () => {
rtlTest(Empty);
it('image size should change', () => {
const wrapper = mount(<Empty imageStyle={{ height: 20 }} />);
expect(wrapper.find('.ant-empty-image').props().style.height).toBe(20);
const { container } = render(<Empty imageStyle={{ height: 20 }} />);
expect(container.querySelector('.ant-empty-image').style.height).toBe('20px');
});
it('description can be false', () => {
const wrapper = mount(<Empty description={false} />);
expect(wrapper.find('.ant-empty-description').length).toBe(0);
const { container } = render(<Empty description={false} />);
expect(container.querySelector('.ant-empty-description')).toBeFalsy();
});
it('should render in RTL direction', () => {
const wrapper = mount(
const { asFragment } = render(
<ConfigProvider direction="rtl">
<Empty />
</ConfigProvider>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
});
});

View File

@ -283,7 +283,7 @@ validateFields()
### Form.useForm
`type Form.useForm = (): FormInstance`
`type Form.useForm = (): [FormInstance]`
Create Form instance to maintain data store.

View File

@ -282,7 +282,7 @@ validateFields()
### Form.useForm
`type Form.useForm = (): FormInstance`
`type Form.useForm = (): [FormInstance]`
创建 Form 实例,用于管理所有数据状态。

View File

@ -21,6 +21,8 @@ const localeValues: Locale = {
filterConfirm: 'Aceptar',
filterReset: 'Reiniciar',
filterEmptyText: 'Sin filtros',
filterCheckall: 'Seleccionar todo',
filterSearchPlaceholder: 'Buscar en filtros',
emptyText: 'Sin datos',
selectAll: 'Seleccionar todo',
selectInvert: 'Invertir selección',

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,7 @@
import React from 'react';
import { mount } from 'enzyme';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import Segmented from '../index';
@ -86,10 +88,7 @@ describe('Segmented', () => {
it('render segmented with string options', () => {
const handleValueChange = jest.fn();
const wrapper = mount(
<Segmented
options={['Daily', 'Weekly', 'Monthly']}
onChange={handleValueChange}
/>,
<Segmented options={['Daily', 'Weekly', 'Monthly']} onChange={handleValueChange} />,
);
expect(wrapper.render()).toMatchSnapshot();
@ -356,4 +355,25 @@ describe('Segmented', () => {
expect(wrapper.find(`.${prefixCls}`).at(0).hasClass(`${prefixCls}-lg`)).toBeTruthy();
});
it('render with icons', () => {
const wrapper = mount(
<Segmented
options={[
{
value: 'List',
icon: <BarsOutlined />,
},
{
value: 'Kanban',
label: 'KanbanYes',
icon: <AppstoreOutlined />,
},
]}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(wrapper.find(`span.${prefixCls}-item-icon`).length).toBe(2);
expect(wrapper.find(`div.${prefixCls}-item-label`).at(1).contains('KanbanYes')).toBeTruthy();
});
});

View File

@ -1,5 +1,5 @@
---
order: 10
order: 1
title:
zh-CN: Block 分段选择器
en-US: Block Segmented

View File

@ -1,5 +1,5 @@
---
order: 0
order: 3
title:
zh-CN: 受控模式
en-US: Controlled mode

View File

@ -1,5 +1,5 @@
---
order: 1
order: 4
title:
zh-CN: 自定义渲染
en-US: Custom Render
@ -23,28 +23,28 @@ export default () => (
options={[
{
label: (
<>
<div style={{ padding: 4 }}>
<Avatar src="https://joeschmoe.io/api/v1/random" />
<div>User 1</div>
</>
</div>
),
value: 'user1',
},
{
label: (
<>
<div style={{ padding: 4 }}>
<Avatar style={{ backgroundColor: '#f56a00' }}>K</Avatar>
<div>User 2</div>
</>
</div>
),
value: 'user2',
},
{
label: (
<>
<div style={{ padding: 4 }}>
<Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} />
<div>User 3</div>
</>
</div>
),
value: 'user3',
},
@ -55,37 +55,37 @@ export default () => (
options={[
{
label: (
<>
<div style={{ padding: 4 }}>
<div>Spring</div>
<div>Jan-Mar</div>
</>
</div>
),
value: 'spring',
},
{
label: (
<>
<div style={{ padding: 4 }}>
<div>Summer</div>
<div>Apr-Jun</div>
</>
</div>
),
value: 'summer',
},
{
label: (
<>
<div style={{ padding: 4 }}>
<div>Autumn</div>
<div>Jul-Sept</div>
</>
</div>
),
value: 'autumn',
},
{
label: (
<>
<div style={{ padding: 4 }}>
<div>Winter</div>
<div>Oct-Dec</div>
</>
</div>
),
value: 'winter',
},

View File

@ -1,5 +1,5 @@
---
order: 0
order: 2
title:
zh-CN: 不可用
en-US: Basic

View File

@ -1,5 +1,5 @@
---
order: 0
order: 5
title:
zh-CN: 动态数据
en-US: Dynamic

View File

@ -0,0 +1,34 @@
---
order: 8
title:
zh-CN: 只设置图标
en-US: With Icon only
---
## zh-CN
在 Segmented Item 选项中只设置 Icon。
## en-US
Set `icon` without `label` for Segmented Item.
```jsx
import { Segmented } from 'antd';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
export default () => (
<Segmented
options={[
{
value: 'List',
icon: <BarsOutlined />,
},
{
value: 'Kanban',
icon: <AppstoreOutlined />,
},
]}
/>
);
```

View File

@ -0,0 +1,40 @@
---
order: 99
title:
zh-CN: 统一高度
en-US: Consistent height
debug: true
---
## zh-CN
与其他组件保持统一高度。
## en-US
Keep consistent height with other components.
```jsx
import { Button, Input, Select, Segmented } from 'antd';
export default () => (
<>
<div>
<Segmented style={{ marginRight: 6 }} size="large" options={['Daily', 'Weekly', 'Monthly']} />
<Button type="primary" size="large">
Button
</Button>
</div>
<div>
<Segmented style={{ marginRight: 6 }} options={['Daily', 'Weekly', 'Monthly']} />
<Input placeholder="default size" style={{ width: 150 }} />
</div>
<div>
<Segmented style={{ marginRight: 6 }} size="small" options={['Daily', 'Weekly', 'Monthly']} />
<Select size="small" defaultValue="lucy" style={{ width: 150 }}>
<Select.Option value="lucy">Lucy</Select.Option>
</Select>
</div>
</>
);
```

View File

@ -1,5 +1,5 @@
---
order: 1
order: 6
title:
zh-CN: 三种大小
en-US: Three sizes of Segmented

View File

@ -1,5 +1,5 @@
---
order: 0
order: 7
title:
zh-CN: 设置图标
en-US: With Icon

View File

@ -12,12 +12,27 @@ import SizeContext, { SizeType } from '../config-provider/SizeContext';
export type { SegmentedValue } from 'rc-segmented';
export interface SegmentedLabeledOption extends RcSegmentedLabeledOption {
/** Set icon for Segmented item */
icon?: React.ReactNode;
interface SegmentedLabeledOptionWithoutIcon extends RcSegmentedLabeledOption {
label: RcSegmentedLabeledOption['label'];
}
export interface SegmentedProps extends Omit<RCSegmentedProps, 'size'> {
interface SegmentedLabeledOptionWithIcon extends Omit<RcSegmentedLabeledOption, 'label'> {
label?: RcSegmentedLabeledOption['label'];
/** Set icon for Segmented item */
icon: React.ReactNode;
}
function isSegmentedLabeledOptionWithIcon(
option: SegmentedRawOption | SegmentedLabeledOptionWithIcon | SegmentedLabeledOptionWithoutIcon,
): option is SegmentedLabeledOptionWithIcon {
return typeof option === 'object' && !!(option as SegmentedLabeledOptionWithIcon)?.icon;
}
export type SegmentedLabeledOption =
| SegmentedLabeledOptionWithIcon
| SegmentedLabeledOptionWithoutIcon;
export interface SegmentedProps extends Omit<RCSegmentedProps, 'size' | 'options'> {
options: (SegmentedRawOption | SegmentedLabeledOption)[];
/** Option to fit width to its parent's width */
block?: boolean;
@ -46,14 +61,14 @@ const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>((props, ref)
const extendedOptions = React.useMemo(
() =>
options.map(option => {
if (typeof option === 'object' && option?.icon) {
if (isSegmentedLabeledOptionWithIcon(option)) {
const { icon, label, ...restOption } = option;
return {
...restOption,
label: (
<>
<span className={`${prefixCls}-item-icon`}>{icon}</span>
<span>{label}</span>
{label && <span>{label}</span>}
</>
),
};

View File

@ -4,26 +4,23 @@
@segmented-prefix-cls: ~'@{ant-prefix}-segmented';
@segmented-container-padding: 2px;
.@{segmented-prefix-cls} {
.reset-component();
position: relative;
display: inline-flex;
align-items: stretch;
justify-items: flex-start;
display: inline-block;
padding: @segmented-container-padding;
color: @segmented-label-color;
background-color: @segmented-bg;
border-radius: 2px;
box-shadow: 0 0 0 2px @segmented-bg;
transition: all 0.3s @ease-in-out;
// hover/focus styles
&:not(&-disabled) {
&:hover,
&:focus {
background-color: @segmented-hover-bg;
box-shadow: 0 0 0 2px @segmented-hover-bg;
}
&-group {
position: relative;
display: flex;
align-items: stretch;
justify-items: flex-start;
width: 100%;
}
// block styles
@ -36,6 +33,14 @@
min-width: 0;
}
// hover/focus styles
&:not(&-disabled) {
&:hover,
&:focus {
background-color: @segmented-hover-bg;
}
}
// item styles
&-item {
position: relative;
@ -54,15 +59,15 @@
}
&-label {
min-height: @input-height-base;
padding: @input-padding-vertical-base @input-padding-horizontal-base;
line-height: @input-height-base - @input-padding-vertical-base * 2;
min-height: @input-height-base - @segmented-container-padding * 2;
padding: 0 @input-padding-horizontal-base;
line-height: @input-height-base - @segmented-container-padding * 2;
.segmented-text-ellipsis();
}
// syntactic sugar to add `icon` for Segmented Item
&-icon {
margin-right: 6px;
&-icon + * {
margin-left: 6px;
}
&-input {
@ -78,20 +83,19 @@
// size styles
&&-lg &-item-label {
min-height: @input-height-lg;
padding: @input-padding-vertical-lg @input-padding-horizontal-lg;
min-height: @input-height-lg - @segmented-container-padding * 2;
padding: 0 @input-padding-horizontal-lg;
font-size: @font-size-lg;
line-height: @input-height-lg - @input-padding-vertical-lg * 2;
line-height: @input-height-lg - @segmented-container-padding * 2;
}
&&-sm &-item-label {
min-height: @input-height-sm;
padding: @input-padding-vertical-sm @input-padding-horizontal-sm;
line-height: @input-height-sm - @input-padding-vertical-sm * 2;
min-height: @input-height-sm - @segmented-container-padding * 2;
padding: 0 @input-padding-horizontal-sm;
line-height: @input-height-sm - @segmented-container-padding * 2;
}
// disabled styles
&-disabled &-item,
&-item-disabled {
.segmented-disabled-item();
}
@ -108,8 +112,8 @@
padding: 4px 0;
}
// transition effect when `enter-active`
&-thumb-motion-enter-active {
// transition effect when `appear-active`
&-thumb-motion-appear-active {
transition: transform 0.3s @ease-in-out, width 0.3s @ease-in-out;
will-change: transform, width;
}

View File

@ -64,7 +64,7 @@ Select component to select value from options.
| status | Set validation status | 'error' \| 'warning' | - | 4.19.0 |
| suffixIcon | The custom suffix icon | ReactNode | - | |
| tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | (props) => ReactNode | - | |
| tokenSeparators | Separator used to tokenize on `tag` and `multiple` mode | string\[] | - | |
| tokenSeparators | Separator used to tokenize, only applies when `mode="tags"` | string\[] | - | |
| value | Current selected option (considered as a immutable array) | string \| string\[]<br />number \| number\[]<br />LabeledValue \| LabeledValue\[] | - | |
| virtual | Disable virtual scroll when set to false | boolean | true | 4.1.0 |
| onBlur | Called when blur | function | - | |

View File

@ -65,7 +65,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| tagRender | 自定义 tag 内容 render仅在 `mode``multiple``tags` 时生效 | (props) => ReactNode | - | |
| tokenSeparators | `tags``multiple` 模式下自动分词的分隔符 | string\[] | - | |
| tokenSeparators | 自动分词的分隔符,仅在 `mode="tags"` 时生效 | string\[] | - | |
| value | 指定当前选中的条目多选时为一个数组。value 数组引用未变化时Select 不会更新) | string \| string\[]<br />number \| number\[]<br />LabeledValue \| LabeledValue\[] | - | |
| virtual | 设置 false 时关闭虚拟滚动 | boolean | true | 4.1.0 |
| onBlur | 失去焦点时回调 | function | - | |

View File

@ -110,7 +110,7 @@
cursor: pointer;
> .@{iconfont-css-prefix} {
vertical-align: -0.2em;
vertical-align: middle;
}
&:hover {

View File

@ -172,4 +172,25 @@ describe('Space', () => {
expect(wrapper.render()).toMatchSnapshot();
});
// https://github.com/ant-design/ant-design/issues/35305
it('should not throw duplicated key warning', () => {
jest.spyOn(console, 'error').mockImplementation(() => undefined);
mount(
<Space>
<div key="1" />
<div />
<div key="3" />
<div />
</Space>,
);
// eslint-disable-next-line no-console
expect(console.error).not.toHaveBeenCalledWith(
expect.stringContaining('Encountered two children with the same key'),
expect.anything(),
expect.anything(),
);
// eslint-disable-next-line no-console
console.error.mockRestore();
});
});

View File

@ -17,22 +17,20 @@ Crowded components horizontal spacing.
import { Button, Space, Upload, Popconfirm } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
function SpaceDemo() {
return (
<Space>
Space
<Button type="primary">Button</Button>
<Upload>
<Button>
<UploadOutlined /> Click to Upload
</Button>
</Upload>
<Popconfirm title="Are you sure delete this task?" okText="Yes" cancelText="No">
<Button>Confirm</Button>
</Popconfirm>
</Space>
);
}
const App = () => (
<Space>
Space
<Button type="primary">Button</Button>
<Upload>
<Button>
<UploadOutlined /> Click to Upload
</Button>
</Upload>
<Popconfirm title="Are you sure delete this task?" okText="Yes" cancelText="No">
<Button>Confirm</Button>
</Popconfirm>
</Space>
);
export default () => <SpaceDemo />;
export default App;
```

View File

@ -17,7 +17,7 @@ Custom spacing size.
import React, { useState } from 'react';
import { Space, Slider, Button } from 'antd';
function SpaceCustomizeSize() {
function App() {
const [size, setSize] = useState(8);
return (
@ -35,5 +35,5 @@ function SpaceCustomizeSize() {
);
}
export default () => <SpaceCustomizeSize />;
export default App;
```

View File

@ -21,7 +21,7 @@ Set the size to `large` and `middle` by setting size to large and middle respect
import React, { useState } from 'react';
import { Space, Radio, Button } from 'antd';
function SpaceSize() {
function App() {
const [size, setSize] = useState('small');
return (
@ -43,5 +43,5 @@ function SpaceSize() {
);
}
export default () => <SpaceSize />;
export default App;
```

View File

@ -16,15 +16,13 @@ Crowded components split.
```jsx
import { Space, Typography, Divider } from 'antd';
function SpaceSplit() {
return (
<Space split={<Divider type="vertical" />}>
<Typography.Link>Link</Typography.Link>
<Typography.Link>Link</Typography.Link>
<Typography.Link>Link</Typography.Link>
</Space>
);
}
const App = () => (
<Space split={<Divider type="vertical" />}>
<Typography.Link>Link</Typography.Link>
<Typography.Link>Link</Typography.Link>
<Typography.Link>Link</Typography.Link>
</Space>
);
export default () => <SpaceSplit />;
export default App;
```

View File

@ -16,24 +16,22 @@ Crowded components vertical spacing.
```jsx
import { Space, Card } from 'antd';
function SpaceVertical() {
return (
<Space direction="vertical" size="middle" style={{ display: 'flex' }}>
<Card title="Card" size="small">
<p>Card content</p>
<p>Card content</p>
</Card>
<Card title="Card" size="small">
<p>Card content</p>
<p>Card content</p>
</Card>
<Card title="Card" size="small">
<p>Card content</p>
<p>Card content</p>
</Card>
</Space>
);
}
const App = () => (
<Space direction="vertical" size="middle" style={{ display: 'flex' }}>
<Card title="Card" size="small">
<p>Card content</p>
<p>Card content</p>
</Card>
<Card title="Card" size="small">
<p>Card content</p>
<p>Card content</p>
</Card>
<Card title="Card" size="small">
<p>Card content</p>
<p>Card content</p>
</Card>
</Space>
);
export default () => <SpaceVertical />;
export default App;
```

View File

@ -16,7 +16,7 @@ Auto wrap line.
```jsx
import { Space, Button } from 'antd';
const Demo = () => (
const App = () => (
<Space size={[8, 16]} wrap>
{new Array(20).fill(null).map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
@ -25,5 +25,5 @@ const Demo = () => (
</Space>
);
export default Demo;
export default App;
```

View File

@ -89,11 +89,14 @@ const Space: React.FC<SpaceProps> = props => {
}
const keyOfChild = child && child.key;
// Add `-space-item` as suffix in case simple key string trigger duplicated key warning
// https://github.com/ant-design/ant-design/issues/35305
const defaultKey = `${i}-space-item`;
return (
<Item
className={itemClassName}
key={`${itemClassName}-${keyOfChild || i}`}
key={`${itemClassName}-${keyOfChild || defaultKey}`}
direction={direction}
index={i}
marginDirection={marginDirection}

View File

@ -872,7 +872,7 @@
@breadcrumb-font-size: @font-size-base;
@breadcrumb-icon-font-size: @font-size-base;
@breadcrumb-link-color: @text-color-secondary;
@breadcrumb-link-color-hover: @primary-5;
@breadcrumb-link-color-hover: @text-color;
@breadcrumb-separator-color: @text-color-secondary;
@breadcrumb-separator-margin: 0 @padding-xs;

View File

@ -927,7 +927,7 @@
@breadcrumb-font-size: @font-size-base;
@breadcrumb-icon-font-size: @font-size-base;
@breadcrumb-link-color: @text-color-secondary;
@breadcrumb-link-color-hover: @primary-5;
@breadcrumb-link-color-hover: @text-color;
@breadcrumb-separator-color: @text-color-secondary;
@breadcrumb-separator-margin: 0 @padding-xs;

View File

@ -18,7 +18,7 @@
line-height: @switch-height;
vertical-align: middle;
background-image: linear-gradient(to right, @disabled-color, @disabled-color),
linear-gradient(to right, @white, @white);
linear-gradient(to right, @component-background, @component-background);
border: 0;
border-radius: 100px;
cursor: pointer;

View File

@ -119,6 +119,18 @@ describe('Table.sorter', () => {
expect(getNameColumn().prop('aria-sort')).toEqual('descending');
});
it('sort records with keydown', () => {
const wrapper = mount(createTable());
// ascend
wrapper.find('.ant-table-column-sorters').simulate('keydown', { keyCode: 13 });
expect(renderedNames(wrapper)).toEqual(['Jack', 'Jerry', 'Lucy', 'Tom']);
// descend
wrapper.find('.ant-table-column-sorters').simulate('keydown', { keyCode: 13 });
expect(renderedNames(wrapper)).toEqual(['Tom', 'Lucy', 'Jack', 'Jerry']);
});
describe('can be controlled by sortOrder', () => {
it('single', () => {
const wrapper = mount(

View File

@ -7,6 +7,7 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -98,6 +99,7 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
<th
aria-sort="ascending"
class="ant-table-cell ant-table-column-sort ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"

View File

@ -36,6 +36,7 @@ exports[`renders ./components/table/demo/ajax.md extend context correctly 1`] =
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -1516,6 +1517,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.md extend context c
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -3205,6 +3207,7 @@ Array [
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -3514,6 +3517,7 @@ Array [
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -7454,6 +7458,7 @@ exports[`renders ./components/table/demo/filter-in-tree.md extend context correc
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -8273,6 +8278,7 @@ exports[`renders ./components/table/demo/filter-search.md extend context correct
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -12145,6 +12151,7 @@ exports[`renders ./components/table/demo/grouping-columns.md extend context corr
<th
class="ant-table-cell ant-table-column-has-sorters"
rowspan="3"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -13250,6 +13257,7 @@ exports[`renders ./components/table/demo/head.md extend context correctly 1`] =
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -13713,6 +13721,7 @@ exports[`renders ./components/table/demo/head.md extend context correctly 1`] =
<th
aria-sort="descending"
class="ant-table-cell ant-table-column-sort ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -14574,6 +14583,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -14657,6 +14667,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -14740,6 +14751,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md extend context corre
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -17420,6 +17432,7 @@ Array [
<tr>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -17724,6 +17737,7 @@ Array [
</th>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -17807,6 +17821,7 @@ Array [
</th>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -18347,6 +18362,7 @@ exports[`renders ./components/table/demo/resizable-column.md extend context corr
</th>
<th
class="ant-table-cell ant-table-column-has-sorters react-resizable"
tabindex="0"
>
<div
class="ant-table-column-sorters"

View File

@ -36,6 +36,7 @@ exports[`renders ./components/table/demo/ajax.md correctly 1`] = `
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -1134,6 +1135,7 @@ exports[`renders ./components/table/demo/custom-filter-panel.md correctly 1`] =
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -2714,6 +2716,7 @@ Array [
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -2811,6 +2814,7 @@ Array [
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -5773,6 +5777,7 @@ exports[`renders ./components/table/demo/filter-in-tree.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -6118,6 +6123,7 @@ exports[`renders ./components/table/demo/filter-search.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -9316,6 +9322,7 @@ exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = `
<th
class="ant-table-cell ant-table-column-has-sorters"
rowspan="3"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -10281,6 +10288,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -10355,6 +10363,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
<th
aria-sort="descending"
class="ant-table-cell ant-table-column-sort ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -11004,6 +11013,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -11063,6 +11073,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -11122,6 +11133,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -13662,6 +13674,7 @@ Array [
<tr>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -13754,6 +13767,7 @@ Array [
</th>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-column-sorters"
@ -13813,6 +13827,7 @@ Array [
</th>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
tabindex="0"
>
<div
class="ant-table-filter-column"
@ -14141,6 +14156,7 @@ exports[`renders ./components/table/demo/resizable-column.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-has-sorters react-resizable"
tabindex="0"
>
<div
class="ant-table-column-sorters"

View File

@ -2,6 +2,7 @@ import * as React from 'react';
import classNames from 'classnames';
import CaretDownOutlined from '@ant-design/icons/CaretDownOutlined';
import CaretUpOutlined from '@ant-design/icons/CaretUpOutlined';
import KeyCode from 'rc-util/lib/KeyCode';
import {
TransformColumns,
ColumnsType,
@ -104,7 +105,7 @@ function collectSortStates<RecordType>(
function injectSorter<RecordType>(
prefixCls: string,
columns: ColumnsType<RecordType>,
sorterSates: SortState<RecordType>[],
sorterStates: SortState<RecordType>[],
triggerSorter: (sorterSates: SortState<RecordType>) => void,
defaultSortDirections: SortOrder[],
tableLocale?: TableLocale,
@ -122,7 +123,7 @@ function injectSorter<RecordType>(
? tableShowSorterTooltip
: newColumn.showSorterTooltip;
const columnKey = getColumnKey(newColumn, columnPos);
const sorterState = sorterSates.find(({ key }) => key === columnKey);
const sorterState = sorterStates.find(({ key }) => key === columnKey);
const sorterOrder = sorterState ? sorterState.sortOrder : null;
const nextSortOrder = nextSortDirection(sortDirections, sorterOrder);
const upNode: React.ReactNode = sortDirections.includes(ASCEND) && (
@ -179,6 +180,7 @@ function injectSorter<RecordType>(
const cell: React.HTMLAttributes<HTMLElement> =
(column.onHeaderCell && column.onHeaderCell(col)) || {};
const originOnClick = cell.onClick;
const originOKeyDown = cell.onKeyDown;
cell.onClick = (event: React.MouseEvent<HTMLElement>) => {
triggerSorter({
column,
@ -186,9 +188,17 @@ function injectSorter<RecordType>(
sortOrder: nextSortOrder,
multiplePriority: getMultiplePriority(column),
});
if (originOnClick) {
originOnClick(event);
originOnClick?.(event);
};
cell.onKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
if (event.keyCode === KeyCode.ENTER) {
triggerSorter({
column,
key: columnKey,
sortOrder: nextSortOrder,
multiplePriority: getMultiplePriority(column),
});
originOKeyDown?.(event);
}
};
@ -202,6 +212,7 @@ function injectSorter<RecordType>(
}
cell.className = classNames(cell.className, `${prefixCls}-column-has-sorters`);
cell.tabIndex = 0;
return cell;
},
@ -214,7 +225,7 @@ function injectSorter<RecordType>(
children: injectSorter(
prefixCls,
newColumn.children,
sorterSates,
sorterStates,
triggerSorter,
defaultSortDirections,
tableLocale,

View File

@ -216,6 +216,7 @@
// ============================ Sorter ============================
&-thead th.@{table-prefix-cls}-column-has-sorters {
outline: none;
cursor: pointer;
transition: all 0.3s;
@ -227,6 +228,10 @@
}
}
&:focus-visible {
color: @primary-color;
}
// https://github.com/ant-design/ant-design/issues/30969
&.@{table-prefix-cls}-cell-fix-left:hover,
&.@{table-prefix-cls}-cell-fix-right:hover {

View File

@ -28,7 +28,7 @@ Ant Design has 3 types of Tabs for different situations.
| centered | Centers tabs | boolean | false | 4.4.0 |
| defaultActiveKey | Initial active TabPane's key, if `activeKey` is not set | string | - | |
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | false | |
| moreIcon | The custom icon of ellipsis | ReactNode | &lt;EllipsisOutlined /> | 4.14.0 |
| moreIcon | The custom icon of ellipsis | ReactNode | &lt;EllipsisOutlined /> | 4.14.0 |
| renderTabBar | Replace the TabBar | (props: DefaultTabBarProps, DefaultTabBar: React.ComponentClass) => React.ReactElement | - | |
| size | Preset tab bar size | `large` \| `default` \| `small` | `default` | |
| tabBarExtraContent | Extra content in tab bar | ReactNode \| {left?: ReactNode, right?: ReactNode} | - | object: 4.6.0 |
@ -38,7 +38,7 @@ Ant Design has 3 types of Tabs for different situations.
| destroyInactiveTabPane | Whether destroy inactive TabPane when change tab | boolean | false | |
| type | Basic style of tabs | `line` \| `card` \| `editable-card` | `line` | |
| onChange | Callback executed when active tab is changed | function(activeKey) {} | - | |
| onEdit | Callback executed when tab is added or removed. Only works while `type="editable-card"` | (targetKey, action) => void | - | |
| onEdit | Callback executed when tab is added or removed. Only works while `type="editable-card"` | (action === 'add' ? event : targetKey, action): void | - | |
| onTabClick | Callback executed when tab is clicked | function(key: string, event: MouseEvent) | - | |
| onTabScroll | Trigger when tab scroll | function({ direction: `left` \| `right` \| `top` \| `bottom` }) | - | 4.3.0 |

View File

@ -41,15 +41,15 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
| destroyInactiveTabPane | 被隐藏时是否销毁 DOM 结构 | boolean | false | |
| type | 页签的基本样式,可选 `line`、`card` `editable-card` 类型 | string | `line` | |
| onChange | 切换面板的回调 | function(activeKey) {} | - | |
| onEdit | 新增和删除页签的回调,在 `type="editable-card"` 时有效 | (targetKey, action): void | - | |
| onEdit | 新增和删除页签的回调,在 `type="editable-card"` 时有效 | (action === 'add' ? event : targetKey, action): void | - | |
| onTabClick | tab 被点击的回调 | function(key: string, event: MouseEvent) | - | |
| onTabScroll | tab 滚动时触发 | function({ direction: `left` \| `right` \| `top` \| `bottom` }) | - | 4.3.0 |
### Tabs.TabPane
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| closeIcon | 自定义关闭图标,`在 type="editable-card"`时有效 | ReactNode | - |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |
| key | 对应 activeKey | string | - |
| tab | 选项卡头显示文字 | ReactNode | - |
| 参数 | 说明 | 类型 | 默认值 |
| ----------- | ----------------------------------------------- | --------- | ------ |
| closeIcon | 自定义关闭图标,`在 type="editable-card"`时有效 | ReactNode | - |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |
| key | 对应 activeKey | string | - |
| tab | 选项卡头显示文字 | ReactNode | - |

View File

@ -21,7 +21,7 @@ One or more elements can be selected from either column, one click on the proper
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| dataSource | Used for setting the source data. The elements that are part of this array will be present the left column. Except the elements whose keys are included in `targetKeys` prop | [RecordType extends TransferItem = TransferItem](https://git.io/vMM64)\[] | \[] | |
| dataSource | Used for setting the source data. The elements that are part of this array will be present the left column. Except the elements whose keys are included in `targetKeys` prop | [RecordType extends TransferItem = TransferItem](https://github.com/ant-design/ant-design/blob/1bf0bab2a7bc0a774119f501806e3e0e3a6ba283/components/transfer/index.tsx#L12)\[] | \[] | |
| disabled | Whether disabled transfer | boolean | false | |
| filterOption | A function to determine whether an item should show in search result list | (inputValue, option): boolean | - | |
| footer | A function used for rendering the footer | (props, { direction }) => ReactNode | - | direction: 4.17.0 |

View File

@ -24,7 +24,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/QAXskNI4G/Transfer.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| dataSource | 数据源,其中的数据将会被渲染到左边一栏中,`targetKeys` 中指定的除外 | [RecordType extends TransferItem = TransferItem](https://git.io/vMM64)\[] | \[] | |
| dataSource | 数据源,其中的数据将会被渲染到左边一栏中,`targetKeys` 中指定的除外 | [RecordType extends TransferItem = TransferItem](https://github.com/ant-design/ant-design/blob/1bf0bab2a7bc0a774119f501806e3e0e3a6ba283/components/transfer/index.tsx#L12)\[] | \[] | |
| disabled | 是否禁用 | boolean | false | |
| filterOption | 接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 true反之则返回 false | (inputValue, option): boolean | - | |
| footer | 底部渲染函数 | (props, { direction }) => ReactNode | - | direction: 4.17.0 |

View File

@ -273,113 +273,6 @@ exports[`Upload List should be uploading when upload a file 1`] = `
</span>
`;
exports[`Upload List should be uploading when upload a file 2`] = `
<span
class=""
>
<div
class="ant-upload ant-upload-select ant-upload-select-text"
>
<span
class="ant-upload"
role="button"
tabindex="0"
>
<input
accept=""
style="display: none;"
type="file"
/>
<button
type="button"
>
upload
</button>
</span>
</div>
<div
class="ant-upload-list ant-upload-list-text"
>
<div
class="ant-upload-list-text-container ant-upload-animate-appear ant-upload-animate-appear-start ant-upload-animate"
style="height: 0px; opacity: 0;"
>
<div
class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-text"
>
<div
class="ant-upload-list-item-info"
>
<span
class="ant-upload-span"
>
<div
class="ant-upload-text-icon"
>
<span
aria-label="paper-clip"
class="anticon anticon-paper-clip"
role="img"
>
<svg
aria-hidden="true"
data-icon="paper-clip"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 00174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"
/>
</svg>
</span>
</div>
<span
class="ant-upload-list-item-name"
title="foo.png"
>
foo.png
</span>
<span
class="ant-upload-list-item-card-actions"
>
<button
class="ant-btn ant-btn-text ant-btn-sm ant-btn-icon-only ant-upload-list-item-card-actions-btn"
title="Remove file"
type="button"
>
<span
aria-label="delete"
class="anticon anticon-delete"
role="img"
tabindex="-1"
>
<svg
aria-hidden="true"
data-icon="delete"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
/>
</svg>
</span>
</button>
</span>
</span>
</div>
</div>
</div>
</div>
</span>
`;
exports[`Upload List should non-image format file preview 1`] = `
<span
class=""

View File

@ -160,9 +160,13 @@ describe('Upload List', () => {
expect(wrapper.render()).toMatchSnapshot();
}
if (file.status === 'done') {
expect(wrapper.render()).toMatchSnapshot();
wrapper.unmount();
done();
(async function run() {
await sleep(200);
wrapper.update();
// expect(wrapper.render()).toMatchSnapshot();
wrapper.unmount();
done();
})();
}
latestFileList = eventFileList;

View File

@ -1,6 +1,6 @@
{
"name": "antd",
"version": "4.20.1",
"version": "4.20.2",
"description": "An enterprise-class UI design language and React components implementation",
"title": "Ant Design",
"keywords": [
@ -142,7 +142,7 @@
"rc-progress": "~3.2.1",
"rc-rate": "~2.9.0",
"rc-resize-observer": "^1.2.0",
"rc-segmented": "~2.0.0",
"rc-segmented": "~2.1.0 ",
"rc-select": "~14.1.1",
"rc-slider": "~10.0.0",
"rc-steps": "~4.1.0",

View File

@ -1,15 +1,15 @@
import React from 'react';
import { mount } from 'enzyme';
import { render } from '../utils';
// eslint-disable-next-line jest/no-export
export default function mountTest(Component: React.ComponentType) {
describe(`mount and unmount`, () => {
// https://github.com/ant-design/ant-design/pull/18441
it(`component could be updated and unmounted without errors`, () => {
const wrapper = mount(<Component />);
const { unmount, rerender } = render(<Component />);
expect(() => {
wrapper.setProps({});
wrapper.unmount();
rerender(<Component />);
unmount();
}).not.toThrow();
});
});