diff --git a/components/locale/default.tsx b/components/locale/default.tsx
index d12c1a89de..06cea25102 100644
--- a/components/locale/default.tsx
+++ b/components/locale/default.tsx
@@ -24,6 +24,7 @@ const localeValues: Locale = {
emptyText: 'No data',
selectAll: 'Select current page',
selectInvert: 'Invert current page',
+ selectNone: 'Clear all data',
selectionAll: 'Select all data',
sortTitle: 'Sort',
expand: 'Expand row',
diff --git a/components/locale/zh_CN.tsx b/components/locale/zh_CN.tsx
index 425de93dd3..79635e5613 100644
--- a/components/locale/zh_CN.tsx
+++ b/components/locale/zh_CN.tsx
@@ -24,6 +24,7 @@ const localeValues: Locale = {
filterEmptyText: '无筛选项',
selectAll: '全选当页',
selectInvert: '反选当页',
+ selectNone: '清空所有',
selectionAll: '全选所有',
sortTitle: '排序',
expand: '展开行',
diff --git a/components/locale/zh_HK.tsx b/components/locale/zh_HK.tsx
index 193b83ab1a..8a148c892a 100644
--- a/components/locale/zh_HK.tsx
+++ b/components/locale/zh_HK.tsx
@@ -23,6 +23,7 @@ const localeValues: Locale = {
filterEmptyText: '無篩選項',
selectAll: '全部選取',
selectInvert: '反向選取',
+ selectNone: '清空所有',
selectionAll: '全選所有',
sortTitle: '排序',
expand: '展開行',
diff --git a/components/locale/zh_TW.tsx b/components/locale/zh_TW.tsx
index 5139e673d9..6dcbb8324f 100644
--- a/components/locale/zh_TW.tsx
+++ b/components/locale/zh_TW.tsx
@@ -23,6 +23,7 @@ const localeValues: Locale = {
filterEmptyText: '無篩選項',
selectAll: '全部選取',
selectInvert: '反向選取',
+ selectNone: '清空所有',
selectionAll: '全選所有',
sortTitle: '排序',
expand: '展開行',
diff --git a/components/table/Table.tsx b/components/table/Table.tsx
index 5136a097d7..5639b088df 100644
--- a/components/table/Table.tsx
+++ b/components/table/Table.tsx
@@ -26,7 +26,11 @@ import {
TableLocale,
TableAction,
} from './interface';
-import useSelection, { SELECTION_ALL, SELECTION_INVERT } from './hooks/useSelection';
+import useSelection, {
+ SELECTION_ALL,
+ SELECTION_INVERT,
+ SELECTION_NONE,
+} from './hooks/useSelection';
import useSorter, { getSortData, SortState } from './hooks/useSorter';
import useFilter, { getFilterData, FilterState } from './hooks/useFilter';
import useTitleColumns from './hooks/useTitleColumns';
@@ -509,6 +513,7 @@ Table.defaultProps = {
Table.SELECTION_ALL = SELECTION_ALL;
Table.SELECTION_INVERT = SELECTION_INVERT;
+Table.SELECTION_NONE = SELECTION_NONE;
Table.Column = Column;
Table.ColumnGroup = ColumnGroup;
Table.Summary = Summary;
diff --git a/components/table/__tests__/Table.rowSelection.test.js b/components/table/__tests__/Table.rowSelection.test.js
index fa5a51d95d..9c356d1a1a 100644
--- a/components/table/__tests__/Table.rowSelection.test.js
+++ b/components/table/__tests__/Table.rowSelection.test.js
@@ -294,11 +294,28 @@ describe('Table.rowSelection', () => {
checkboxes.at(1).simulate('change', { target: { checked: true } });
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
- dropdownWrapper.find('.ant-dropdown-menu-item').last().simulate('click');
+ dropdownWrapper.find('.ant-dropdown-menu-item').at(1).simulate('click');
expect(handleSelectInvert).toHaveBeenCalledWith([1, 2, 3]);
});
+ it('fires selectNone event', () => {
+ const handleSelectNone = jest.fn();
+ const rowSelection = {
+ onSelectNone: handleSelectNone,
+ selections: true,
+ };
+ const wrapper = mount(createTable({ rowSelection }));
+ const checkboxes = wrapper.find('input');
+
+ checkboxes.at(1).simulate('change', { target: { checked: true } });
+
+ const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
+ dropdownWrapper.find('.ant-dropdown-menu-item').last().simulate('click');
+
+ expect(handleSelectNone).toHaveBeenCalled();
+ });
+
it('fires selection event', () => {
const handleSelectOdd = jest.fn();
const handleSelectEven = jest.fn();
diff --git a/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap b/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap
index 221eec1058..adb6ad8554 100644
--- a/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap
+++ b/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap
@@ -984,6 +984,12 @@ exports[`Table.rowSelection render with default selection correctly 1`] = `
>
Invert current page
+
@@ -1093,6 +1099,12 @@ exports[`Table.rowSelection should support getPopupContainer 1`] = `
>
Invert current page
+
@@ -1420,6 +1432,12 @@ exports[`Table.rowSelection should support getPopupContainer from ConfigProvider
>
Invert current page
+
diff --git a/components/table/demo/row-selection-custom.md b/components/table/demo/row-selection-custom.md
index 4e150e1389..490f353e9f 100644
--- a/components/table/demo/row-selection-custom.md
+++ b/components/table/demo/row-selection-custom.md
@@ -59,6 +59,7 @@ class App extends React.Component {
selections: [
Table.SELECTION_ALL,
Table.SELECTION_INVERT,
+ Table.SELECTION_NONE,
{
key: 'odd',
text: 'Select Odd Row',
diff --git a/components/table/hooks/useSelection.tsx b/components/table/hooks/useSelection.tsx
index 36e99d2bcc..f224535c44 100644
--- a/components/table/hooks/useSelection.tsx
+++ b/components/table/hooks/useSelection.tsx
@@ -28,6 +28,7 @@ import {
// TODO: warning if use ajax!!!
export const SELECTION_ALL = 'SELECT_ALL' as const;
export const SELECTION_INVERT = 'SELECT_INVERT' as const;
+export const SELECTION_NONE = 'SELECT_NONE' as const;
function getFixedType(column: ColumnsType[number]): FixedType | undefined {
return column && column.fixed;
@@ -49,7 +50,8 @@ interface UseSelectionConfig {
export type INTERNAL_SELECTION_ITEM =
| SelectionItem
| typeof SELECTION_ALL
- | typeof SELECTION_INVERT;
+ | typeof SELECTION_INVERT
+ | typeof SELECTION_NONE;
function flattenData(
data: RecordType[] | undefined,
@@ -82,6 +84,7 @@ export default function useSelection(
onSelect,
onSelectAll,
onSelectInvert,
+ onSelectNone,
onSelectMultiple,
columnWidth: selectionColWidth,
type: selectionType,
@@ -255,7 +258,7 @@ export default function useSelection(
}
const selectionList: INTERNAL_SELECTION_ITEM[] =
- selections === true ? [SELECTION_ALL, SELECTION_INVERT] : selections;
+ selections === true ? [SELECTION_ALL, SELECTION_INVERT, SELECTION_NONE] : selections;
return selectionList.map((selection: INTERNAL_SELECTION_ITEM) => {
if (selection === SELECTION_ALL) {
@@ -296,6 +299,18 @@ export default function useSelection(
},
};
}
+ if (selection === SELECTION_NONE) {
+ return {
+ key: 'none',
+ text: tableLocale.selectNone,
+ onSelect() {
+ setSelectedKeys([]);
+ if (onSelectNone) {
+ onSelectNone();
+ }
+ },
+ };
+ }
return selection as SelectionItem;
});
}, [selections, derivedSelectedKeySet, pageData, getRowKey, onSelectInvert, setSelectedKeys]);
diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md
index 72bcdba4f9..a5daf86e62 100644
--- a/components/table/index.en-US.md
+++ b/components/table/index.en-US.md
@@ -203,6 +203,7 @@ Properties for row selection.
| onSelect | Callback executed when select/deselect one row | function(record, selected, selectedRows, nativeEvent) | - | |
| onSelectAll | Callback executed when select/deselect all rows | function(selected, selectedRows, changeRows) | - | |
| onSelectInvert | Callback executed when row selection is inverted | function(selectedRowKeys) | - | |
+| onSelectNone | Callback executed when row selection is cleared | function() | - | |
### scroll
diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md
index 6b0cbe017b..390360b1f1 100644
--- a/components/table/index.zh-CN.md
+++ b/components/table/index.zh-CN.md
@@ -210,6 +210,7 @@ const columns = [
| onSelect | 用户手动选择/取消选择某行的回调 | function(record, selected, selectedRows, nativeEvent) | - | |
| onSelectAll | 用户手动选择/取消选择所有行的回调 | function(selected, selectedRows, changeRows) | - | |
| onSelectInvert | 用户手动选择反选的回调 | function(selectedRowKeys) | - | |
+| onSelectNone | 用户清空选择的回调 | function() | - | |
### scroll
diff --git a/components/table/interface.tsx b/components/table/interface.tsx
index b3f7cb2de0..75e4804b67 100644
--- a/components/table/interface.tsx
+++ b/components/table/interface.tsx
@@ -29,6 +29,7 @@ export interface TableLocale {
filterEmptyText?: React.ReactNode;
emptyText?: React.ReactNode | (() => React.ReactNode);
selectAll?: React.ReactNode;
+ selectNone?: React.ReactNode;
selectInvert?: React.ReactNode;
selectionAll?: React.ReactNode;
sortTitle?: string;
@@ -143,6 +144,7 @@ export interface TableRowSelection {
onSelectAll?: (selected: boolean, selectedRows: T[], changeRows: T[]) => void;
/** @deprecated This function is meaningless and should use `onChange` instead */
onSelectInvert?: (selectedRowKeys: Key[]) => void;
+ onSelectNone?: () => void;
selections?: INTERNAL_SELECTION_ITEM[] | boolean;
hideSelectAll?: boolean;
fixed?: boolean;