Merge pull request #25144 from ant-design/master

chore: merge master into feature
This commit is contained in:
二货机器人 2020-06-22 13:20:02 +08:00 committed by GitHub
commit 0313f973bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 448 additions and 64 deletions

View File

@ -15,6 +15,31 @@ timeline: true
---
## 4.3.5
`2020-06-21`
- 🐞 Fix Input.Search as AutoComplete customize component crash issue. [#25049](https://github.com/ant-design/ant-design/pull/25049)
- 🛠 Rewrite Input.Password with hooks. [#25012](https://github.com/ant-design/ant-design/pull/25012) [@Rustin-Liu](https://github.com/Rustin-Liu)
- 🐞 Fix PageHeader tabs broken style since `4.3.0`. [#24991](https://github.com/ant-design/ant-design/pull/24991)
- 🐞 Fix Backtop still interactive when it is hidden. [#25132](https://github.com/ant-design/ant-design/pull/25132) [@jesse3mh9a](https://github.com/jesse3mh9a)
- 🐞 Fix Upload don't support Popover. [#25090](https://github.com/ant-design/ant-design/pull/25090)
- 🐞 Fix Tabs content exceeds container width issue. [#25072](https://github.com/ant-design/ant-design/pull/25072)
- 🐞 Fix DataPicker/TimePicker time dropdown alignment issue. [#25019](https://github.com/ant-design/ant-design/pull/25019)
- Table
- 🐞 Fix Table nested border style. [#24995](https://github.com/ant-design/ant-design/pull/24995)
- 💄 Improve Table empty filters menu UI. [#25073](https://github.com/ant-design/ant-design/pull/25073)
- 💄 Reduce Table filter dropdown's `max-height`. [#25001](https://github.com/ant-design/ant-design/pull/25001)
- Descriptions
- 🐞 Fix Descriptions selecting text behavior when double clicking item. [#24983](https://github.com/ant-design/ant-design/pull/24983) [@harupy](https://github.com/harupy)
- 💄 Fix Descriptions label text not start aligned in Safari. [#25018](https://github.com/ant-design/ant-design/pull/25018)
- 💄 Fix List.Item.Meta content width may overflow sometimes. [#24992](https://github.com/ant-design/ant-design/pull/24992)
- 🐞 Fix dark mode Menu.SubMenu background color in compact theme. [#24997](https://github.com/ant-design/ant-design/pull/24997)
- ⚡️ Reduce 3KB Button css bundle size. [#24996](https://github.com/ant-design/ant-design/pull/24996)
- 🇹🇷 Improve Turkish locale. [#25100](https://github.com/ant-design/ant-design/pull/25100) [@smddzcy](https://github.com/smddzcy)
- TypeScript
- Export Tree `DataNode`. [#25065](https://github.com/ant-design/ant-design/pull/25065) [@jinxin0112](https://github.com/jinxin0112)
## 4.3.4
`2020-06-14`

View File

@ -15,6 +15,31 @@ timeline: true
---
## 4.3.5
`2020-06-21`
- 🐞 修复 Input.Search 作为 AutoComplete 自定义组件会崩溃的问题。[#25049](https://github.com/ant-design/ant-design/pull/25049)
- 🛠 使用 hooks 重写 Input.Password。[#25012](https://github.com/ant-design/ant-design/pull/25012) [@Rustin-Liu](https://github.com/Rustin-Liu)
- 🐞 修复 PageHeader 从 `4.3.0` 后的 `tabs` 样式错误。[#24991](https://github.com/ant-design/ant-design/pull/24991)
- 🐞 修复 Backtop 没有完全隐藏的问题。[#25132](https://github.com/ant-design/ant-design/pull/25132) [@jesse3mh9a](https://github.com/jesse3mh9a)
- 🐞 修复 Upload 不支持包裹 Popover 的问题。[#25090](https://github.com/ant-design/ant-design/pull/25090)
- 🐞 修复 Tabs 内容会超出容器宽度的问题。[#25072](https://github.com/ant-design/ant-design/pull/25072)
- 🐞 修复 DataPicker/TimePicker 时间下拉选对齐问题。[#25019](https://github.com/ant-design/ant-design/pull/25019)
- Table
- 💄 优化 Table 筛选菜单为空时的 UI。[#25073](https://github.com/ant-design/ant-design/pull/25073)
- 🐞 修复 Table 嵌套 Table 时的边框样式问题。[#24995](https://github.com/ant-design/ant-design/pull/24995)
- 💄 缩小了 Table 筛选菜单的最大高度。[#25001](https://github.com/ant-design/ant-design/pull/25001)
- Descriptions
- 🐞 修复 Descriptions 双击会同时选中标签和内容的问题。[#24983](https://github.com/ant-design/ant-design/pull/24983) [@harupy](https://github.com/harupy)
- 💄 修正了 Descriptions 在 Safari 下标签文本没有左侧对齐的问题。[#25018](https://github.com/ant-design/ant-design/pull/25018)
- 💄 修正了 List.Item.Meta 内容宽度有时会溢出的问题。[#24992](https://github.com/ant-design/ant-design/pull/24992)
- 🐞 修复 Menu.SubMenu 在紧凑模式下暗黑主题的背景颜色。[#24997](https://github.com/ant-design/ant-design/pull/24997)
- ⚡️ 减少 Button `3KB` 样式打包体积。[#24996](https://github.com/ant-design/ant-design/pull/24996)
- 🇹🇷 优化土耳其语语言包。[#25100](https://github.com/ant-design/ant-design/pull/25100) [@smddzcy](https://github.com/smddzcy)
- TypeScript
- 导出 Tree `DataNode` 定义。[#25065](https://github.com/ant-design/ant-design/pull/25065) [@jinxin0112](https://github.com/jinxin0112)
## 4.3.4
`2020-06-14`

View File

@ -14,6 +14,10 @@
height: 40px;
cursor: pointer;
&:empty {
display: none;
}
&-rtl {
right: auto;
left: 100px;

View File

@ -325,22 +325,6 @@ exports[`renders ./components/button/demo/ghost.md correctly 1`] = `
Dashed
</span>
</button>
<button
class="ant-btn ant-btn-text ant-btn-background-ghost"
type="button"
>
<span>
Text
</span>
</button>
<button
class="ant-btn ant-btn-link ant-btn-background-ghost"
type="button"
>
<span>
Link
</span>
</button>
</div>
`;

View File

@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { mount, render } from 'enzyme';
import { act } from 'react-dom/test-utils';
import { SearchOutlined } from '@ant-design/icons';
import { resetWarned } from 'rc-util/lib/warning'
import Button from '..';
import ConfigProvider from '../../config-provider';
import mountTest from '../../../tests/shared/mountTest';
@ -281,6 +282,7 @@ describe('Button', () => {
});
it('should warning when pass a string as icon props', () => {
resetWarned()
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
mount(<Button type="primary" icon="ab" />);
expect(warnSpy).not.toHaveBeenCalled();
@ -291,6 +293,26 @@ describe('Button', () => {
warnSpy.mockRestore();
});
it('should warning when pass type=link and ghost=true', () => {
resetWarned()
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
mount(<Button type="link" ghost />);
expect(warnSpy).toHaveBeenCalledWith(
"Warning: [antd: Button] `link` or `text` button can't be a `ghost` button.",
);
warnSpy.mockRestore();
})
it('should warning when pass type=text and ghost=true', () => {
resetWarned()
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
mount(<Button type="text" ghost />);
expect(warnSpy).toHaveBeenCalledWith(
"Warning: [antd: Button] `link` or `text` button can't be a `ghost` button.",
);
warnSpy.mockRestore();
})
it('skip check 2 words when ConfigProvider disable this', () => {
const wrapper = mount(
<ConfigProvider autoInsertSpaceInButton={false}>

View File

@ -18,6 +18,10 @@ function isString(str: any) {
return typeof str === 'string';
}
function isUnborderedButtonType(type: ButtonType | undefined) {
return type === 'text' || type === 'link';
}
// Insert one space between two chinese characters automatically.
function insertSpace(child: React.ReactChild, needInserted: boolean) {
// Check the child if is undefined or null.
@ -147,7 +151,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
const delayTimeoutRef = React.useRef<number>();
const isNeedInserted = () => {
return React.Children.count(children) === 1 && !icon && type !== 'link' && type !== 'text';
return React.Children.count(children) === 1 && !icon && !isUnborderedButtonType(type);
};
const fixTwoCNChar = () => {
@ -204,6 +208,12 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
`\`icon\` is using ReactNode instead of string naming in v4. Please check \`${icon}\` at https://ant.design/components/icon`,
);
devWarning(
!(ghost && isUnborderedButtonType(type)),
'Button',
"`link` or `text` button can't be a `ghost` button.",
);
const prefixCls = getPrefixCls('btn', customizePrefixCls);
const autoInsertSpace = autoInsertSpaceInButton !== false;
@ -228,7 +238,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
[`${prefixCls}-${shape}`]: shape,
[`${prefixCls}-${sizeCls}`]: sizeCls,
[`${prefixCls}-icon-only`]: !children && children !== 0 && iconType,
[`${prefixCls}-background-ghost`]: ghost,
[`${prefixCls}-background-ghost`]: ghost && !isUnborderedButtonType(type),
[`${prefixCls}-loading`]: innerLoading,
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
[`${prefixCls}-block`]: block,
@ -274,7 +284,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
</button>
);
if (type === 'link' || type === 'text') {
if (isUnborderedButtonType(type)) {
return buttonNode;
}

View File

@ -25,12 +25,6 @@ ReactDOM.render(
<Button type="dashed" ghost>
Dashed
</Button>
<Button type="text" ghost>
Text
</Button>
<Button type="link" ghost>
Link
</Button>
</div>,
mountNode,
);

View File

@ -208,12 +208,6 @@
.button-variant-ghost(@btn-danger-border, transparent);
}
&-background-ghost&-link {
.button-variant-ghost(@link-color; transparent);
color: @btn-link-ghost-color;
}
&-two-chinese-chars::first-letter {
letter-spacing: 0.34em;
}

View File

@ -5,8 +5,16 @@ import { PickerLocale } from '../generatePicker';
// Merge into a locale object
const locale: PickerLocale = {
lang: {
placeholder: 'Tarih Seç',
rangePlaceholder: ['Başlangıç Tarihi', 'Bitiş Tarihi'],
placeholder: 'Tarih seç',
yearPlaceholder: 'Yıl seç',
quarterPlaceholder: 'Çeyrek seç',
monthPlaceholder: 'Ay seç',
weekPlaceholder: 'Hafta seç',
rangePlaceholder: ['Başlangıç tarihi', 'Bitiş tarihi'],
rangeYearPlaceholder: ['Başlangıç yılı', 'Bitiş yılı'],
rangeMonthPlaceholder: ['Başlangıç ayı', 'Bitiş ayı'],
rangeWeekPlaceholder: ['Başlangıç haftası', 'Bitiş haftası'],
...CalendarLocale,
},
timePickerLocale: {

View File

@ -243604,7 +243604,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
>
<input
autocomplete="off"
placeholder="Tarih Seç"
placeholder="Tarih seç"
readonly=""
size="12"
title=""
@ -244198,7 +244198,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
>
<input
autocomplete="off"
placeholder="Zaman Seç"
placeholder="Zaman seç"
readonly=""
size="10"
title=""
@ -245606,7 +245606,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
>
<input
autocomplete="off"
placeholder="Başlangıç Tarihi"
placeholder="Başlangıç tarihi"
readonly=""
size="12"
value=""
@ -245646,7 +245646,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
>
<input
autocomplete="off"
placeholder="Bitiş Tarihi"
placeholder="Bitiş tarihi"
readonly=""
size="12"
value=""

View File

@ -1,9 +1,12 @@
/* eslint-disable no-template-curly-in-string */
import Pagination from 'rc-pagination/lib/locale/tr_TR';
import DatePicker from '../date-picker/locale/tr_TR';
import TimePicker from '../time-picker/locale/tr_TR';
import Calendar from '../calendar/locale/tr_TR';
import { Locale } from '../locale-provider';
const typeTemplate = '${label} geçerli bir ${type} değil';
const localeValues: Locale = {
locale: 'tr',
Pagination,
@ -14,12 +17,19 @@ const localeValues: Locale = {
placeholder: 'Lütfen seçiniz',
},
Table: {
filterTitle: 'Menü Filtrele',
filterTitle: 'Filtre menüsü',
filterConfirm: 'Tamam',
filterReset: 'Sıfırla',
selectAll: 'Hepsini Seç',
selectInvert: 'Tersini Seç',
filterEmptyText: 'Filtre yok',
selectAll: 'Tüm sayfayı seç',
selectInvert: 'Tersini seç',
selectionAll: 'Tümünü seç',
sortTitle: 'Sırala',
expand: 'Satırı genişlet',
collapse: 'Satırı daralt',
triggerDesc: 'Azalan düzende sırala',
triggerAsc: 'Artan düzende sırala',
cancelSort: 'Sıralamayı kaldır',
},
Modal: {
okText: 'Tamam',
@ -35,25 +45,83 @@ const localeValues: Locale = {
searchPlaceholder: 'Arama',
itemUnit: 'Öğe',
itemsUnit: 'Öğeler',
remove: 'Kaldır',
selectCurrent: 'Tüm sayfayı seç',
removeCurrent: 'Sayfayı kaldır',
selectAll: 'Tümünü seç',
removeAll: 'Tümünü kaldır',
selectInvert: 'Tersini seç',
},
Upload: {
uploading: 'Yükleniyor...',
removeFile: `Dosyayı kaldır`,
uploadError: 'Yükleme Hatası',
previewFile: `Dosyayı Önizle`,
removeFile: 'Dosyayı kaldır',
uploadError: 'Yükleme hatası',
previewFile: 'Dosyayı önizle',
downloadFile: 'Dosyayı indir',
},
Empty: {
description: 'Veri Yok',
},
Icon: {
icon: 'icon',
icon: 'ikon',
},
Text: {
edit: 'düzenle',
copy: 'kopyala',
copied: 'kopyalandı',
expand: 'genişlet',
edit: 'Düzenle',
copy: 'Kopyala',
copied: 'Kopyalandı',
expand: 'Genişlet',
},
PageHeader: {
back: 'Geri',
},
Form: {
defaultValidateMessages: {
default: 'Alan doğrulama hatası ${label}',
required: '${label} gerekli bir alan',
enum: '${label} şunlardan biri olmalı: [${enum}]',
whitespace: '${label} sadece boşluk olamaz',
date: {
format: '${label} tarih biçimi geçersiz',
parse: '${label} bir tarihe dönüştürülemedi',
invalid: '${label} geçersiz bir tarih',
},
types: {
string: typeTemplate,
method: typeTemplate,
array: typeTemplate,
object: typeTemplate,
number: typeTemplate,
date: typeTemplate,
boolean: typeTemplate,
integer: typeTemplate,
float: typeTemplate,
regexp: typeTemplate,
email: typeTemplate,
url: typeTemplate,
hex: typeTemplate,
},
string: {
len: '${label} ${len} karakter olmalı',
min: '${label} en az ${min} karakter olmalı',
max: '${label} en çok ${max} karakter olmalı',
range: '${label} ${min}-${max} karakter arası olmalı',
},
number: {
len: '${label} ${len} olmalı',
min: '${label} en az ${min} olmalı',
max: '${label} en çok ${max} olmalı',
range: '${label} ${min}-${max} arası olmalı',
},
array: {
len: '${label} sayısı ${len} olmalı',
min: '${label} sayısı en az ${min} olmalı',
max: '${label} sayısı en çok ${max} olmalı',
range: '${label} sayısı ${min}-${max} arası olmalı',
},
pattern: {
mismatch: '${label} şu kalıpla eşleşmeli: ${pattern}',
},
},
},
};

View File

@ -220,7 +220,6 @@
@btn-default-ghost-color: @text-color;
@btn-default-ghost-border: fade(@white, 25%);
@btn-link-ghost-color: @text-color;
@btn-text-hover-bg: rgba(255, 255, 255, 0.03);
// Checkbox

View File

@ -218,7 +218,6 @@
@btn-group-border: @primary-5;
@btn-link-ghost-color: @component-background;
@btn-link-hover-bg: transparent;
@btn-text-hover-bg: rgba(0, 0, 0, 0.018);

View File

@ -1,7 +1,8 @@
import { TimePickerLocale } from '../index';
const locale: TimePickerLocale = {
placeholder: 'Zaman Seç',
placeholder: 'Zaman seç',
rangePlaceholder: ['Başlangıç zamanı', 'Bitiş zamanı'],
};
export default locale;

View File

@ -184,7 +184,12 @@ const DirectoryTree: React.FC<DirectoryTreeProps> = ({
newSelectedKeys = Array.from(
new Set([
...(cachedSelectedKeys.current || []),
...calcRangeKeys(treeData, expandedKeys, key, lastSelectedKey.current),
...calcRangeKeys({
treeData,
expandedKeys,
startKey: key,
endKey: lastSelectedKey.current,
}),
]),
);
newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys);

View File

@ -212,3 +212,147 @@ exports[`Tree switcherIcon in Tree could be string 1`] = `
</div>
</div>
`;
exports[`Tree switcherIcon should be loading icon when loadData 1`] = `
<div
class="ant-tree ant-tree-icon-hide"
>
<div
role="tree"
>
<input
style="width: 0px; height: 0px; display: flex; overflow: hidden; opacity: 0; border: 0px; padding: 0px; margin: 0px;"
tabindex="0"
value=""
/>
</div>
<div
class="ant-tree-list"
>
<div>
<div
class="ant-tree-list-holder-inner"
style="display: flex; flex-direction: column;"
>
<div
class="ant-tree-treenode ant-tree-treenode-switcher-open"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
switcherIcon
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="---"
>
<span
class="ant-tree-title"
>
---
</span>
</span>
</div>
<div
class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-loading"
>
<span
aria-hidden="true"
class="ant-tree-indent"
>
<span
class="ant-tree-indent-unit ant-tree-indent-unit-start"
/>
</span>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<span
aria-label="loading"
class="anticon anticon-loading ant-tree-switcher-loading-icon"
role="img"
>
<svg
aria-hidden="true"
class="anticon-spin"
data-icon="loading"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/>
</svg>
</span>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="node1"
>
<span
class="ant-tree-iconEle ant-tree-icon__open ant-tree-icon_loading"
/>
<span
class="ant-tree-title"
>
node1
</span>
</span>
</div>
<div
class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-loading"
>
<span
aria-hidden="true"
class="ant-tree-indent"
>
<span
class="ant-tree-indent-unit ant-tree-indent-unit-end"
/>
</span>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<span
aria-label="loading"
class="anticon anticon-loading ant-tree-switcher-loading-icon"
role="img"
>
<svg
aria-hidden="true"
class="anticon-spin"
data-icon="loading"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/>
</svg>
</span>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="node2"
>
<span
class="ant-tree-iconEle ant-tree-icon__open ant-tree-icon_loading"
/>
<span
class="ant-tree-title"
>
node2
</span>
</span>
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -197,4 +197,57 @@ describe('Directory Tree', () => {
wrapper.find(TreeNode).find('.ant-tree-node-content-wrapper').at(0).simulate('doubleclick');
expect(onDoubleClick).toBeCalled();
});
it('should not expand tree now when pressing ctrl', () => {
const onExpand = jest.fn();
const onSelect = jest.fn();
const wrapper = mount(createTree({ onExpand, onSelect }));
wrapper
.find(TreeNode)
.find('.ant-tree-node-content-wrapper')
.at(0)
.simulate('click', { ctrlKey: true });
expect(onExpand).not.toHaveBeenCalled();
expect(onSelect).toHaveBeenCalledWith(
['0-0'],
expect.objectContaining({ event: 'select', nativeEvent: expect.anything() }),
);
});
it('should not expand tree now when click leaf node', () => {
const onExpand = jest.fn();
const onSelect = jest.fn();
const wrapper = mount(
createTree({
onExpand,
onSelect,
defaultExpandAll: true,
treeData: [
{
key: '0-0-0',
title: 'Folder',
children: [
{
title: 'Folder2',
key: '0-0-1',
children: [
{
title: 'File',
key: '0-0-2',
isLeaf: true,
},
],
},
],
},
],
}),
);
wrapper.find(TreeNode).last().find('.ant-tree-node-content-wrapper').at(0).simulate('click');
expect(onExpand).not.toHaveBeenCalled();
expect(onSelect).toHaveBeenCalledWith(
['0-0-2'],
expect.objectContaining({ event: 'select', nativeEvent: expect.anything() }),
);
});
});

View File

@ -54,4 +54,23 @@ describe('Tree', () => {
);
expect(wrapper.render()).toMatchSnapshot();
});
it('switcherIcon should be loading icon when loadData', () => {
function onLoadData() {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, 1000);
});
}
const wrapper = mount(
<Tree switcherIcon="switcherIcon" defaultExpandAll loadData={onLoadData}>
<TreeNode icon="icon">
<TreeNode id="node1" title="node1" icon="icon" key="0-0-2" />
<TreeNode id="node2" title="node2" key="0-0-3" />
</TreeNode>
</Tree>,
);
expect(wrapper.render()).toMatchSnapshot();
});
});

View File

@ -1,7 +1,7 @@
import { calcRangeKeys } from '../utils/dictUtil';
describe('Tree util', () => {
it('calc range keys', () => {
describe('calcRangeKeys', () => {
const treeData = [
{ key: '0-0', children: [{ key: '0-0-0' }, { key: '0-0-1' }] },
{ key: '0-1', children: [{ key: '0-1-0' }, { key: '0-1-1' }] },
@ -13,8 +13,33 @@ describe('Tree util', () => {
},
];
const keys = calcRangeKeys(treeData, ['0-0', '0-2', '0-2-0'], '0-2-0-1', '0-0-0');
const target = ['0-0-0', '0-0-1', '0-1', '0-2', '0-2-0', '0-2-0-0', '0-2-0-1'];
expect(keys.sort()).toEqual(target.sort());
it('calc range keys', () => {
const keys = calcRangeKeys({
treeData,
expandedKeys: ['0-0', '0-2', '0-2-0'],
startKey: '0-2-0-1',
endKey: '0-0-0',
});
const target = ['0-0-0', '0-0-1', '0-1', '0-2', '0-2-0', '0-2-0-0', '0-2-0-1'];
expect(keys.sort()).toEqual(target.sort());
});
it('return startKey when startKey === endKey', () => {
const keys = calcRangeKeys({
treeData,
expandedKeys: ['0-0', '0-2', '0-2-0'],
startKey: '0-0-0',
endKey: '0-0-0',
});
expect(keys).toEqual(['0-0-0']);
});
it('return empty array without startKey and endKey', () => {
const keys = calcRangeKeys({
treeData,
expandedKeys: ['0-0', '0-2', '0-2-0'],
});
expect(keys).toEqual([]);
});
});
});

View File

@ -21,12 +21,17 @@ function traverseNodesKey(
}
/** 计算选中范围只考虑expanded情况以优化性能 */
export function calcRangeKeys(
treeData: DataNode[],
expandedKeys: Key[],
startKey?: Key,
endKey?: Key,
): Key[] {
export function calcRangeKeys({
treeData,
expandedKeys,
startKey,
endKey,
}: {
treeData: DataNode[];
expandedKeys: Key[];
startKey?: Key;
endKey?: Key;
}): Key[] {
const keys: Key[] = [];
let record: Record = Record.None;

View File

@ -1,6 +1,6 @@
{
"name": "antd",
"version": "4.3.4",
"version": "4.3.5",
"description": "An enterprise-class UI design language and React components implementation",
"keywords": [
"ant",
@ -192,7 +192,7 @@
"enzyme-adapter-react-16": "^1.14.0",
"enzyme-to-json": "^3.3.5",
"esbuild-webpack-plugin": "^1.0.0",
"eslint": "^7.0.0",
"eslint": "~7.2.0",
"eslint-config-airbnb": "^18.0.0",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-babel": "^5.3.0",