mirror of
https://github.com/ant-design/ant-design.git
synced 2025-08-06 16:06:28 +08:00
Table: add prop sortDirections
for table and column (#13773)
* Table: add prop `sortMethods` with `sortMethods` user can change table sort methods and its order * Table: `sortMethods` can be set on column prop * rename `sortMethods` to `sortDirections`
This commit is contained in:
parent
22daf9e6af
commit
6b6ec278cc
@ -87,6 +87,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
onChange: PropTypes.func,
|
||||
locale: PropTypes.object,
|
||||
dropdownPrefixCls: PropTypes.string,
|
||||
sortDirections: PropTypes.array,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@ -100,6 +101,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
locale: {},
|
||||
rowKey: 'key',
|
||||
showHeader: true,
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
};
|
||||
|
||||
CheckboxPropsCache: {
|
||||
@ -382,18 +384,18 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
if (!column.sorter) {
|
||||
return;
|
||||
}
|
||||
const sortDirections = column.sortDirections || this.props.sortDirections;
|
||||
const { sortOrder, sortColumn } = this.state;
|
||||
// 只同时允许一列进行排序,否则会导致排序顺序的逻辑问题
|
||||
let newSortOrder: 'descend' | 'ascend' | undefined;
|
||||
// 切换另一列时,丢弃 sortOrder 的状态
|
||||
const oldSortOrder = this.isSameColumn(sortColumn, column) ? sortOrder : undefined;
|
||||
// 切换排序状态,按照降序/升序/不排序的顺序
|
||||
if (!oldSortOrder) {
|
||||
newSortOrder = 'ascend';
|
||||
} else if (oldSortOrder === 'ascend') {
|
||||
newSortOrder = 'descend';
|
||||
if (this.isSameColumn(sortColumn, column) && sortOrder !== undefined) {
|
||||
// 按照sortDirections的内容依次切换排序状态
|
||||
const methodIndex = sortDirections.indexOf(sortOrder) + 1;
|
||||
newSortOrder =
|
||||
methodIndex === sortDirections.length ? undefined : sortDirections[methodIndex];
|
||||
} else {
|
||||
newSortOrder = undefined;
|
||||
newSortOrder = sortDirections[0];
|
||||
}
|
||||
|
||||
const newState = {
|
||||
@ -832,20 +834,30 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
);
|
||||
}
|
||||
if (column.sorter) {
|
||||
const sortDirections = column.sortDirections || this.props.sortDirections;
|
||||
const isAscend = isSortColumn && sortOrder === 'ascend';
|
||||
const isDescend = isSortColumn && sortOrder === 'descend';
|
||||
|
||||
const ascend = sortDirections.indexOf('ascend') !== -1 && (
|
||||
<Icon
|
||||
className={`${prefixCls}-column-sorter-up ${isAscend ? 'on' : 'off'}`}
|
||||
type="caret-up"
|
||||
theme="filled"
|
||||
/>
|
||||
);
|
||||
|
||||
const descend = sortDirections.indexOf('descend') !== -1 && (
|
||||
<Icon
|
||||
className={`${prefixCls}-column-sorter-down ${isDescend ? 'on' : 'off'}`}
|
||||
type="caret-down"
|
||||
theme="filled"
|
||||
/>
|
||||
);
|
||||
|
||||
sortButton = (
|
||||
<div className={`${prefixCls}-column-sorter`} key="sorter">
|
||||
<Icon
|
||||
className={`${prefixCls}-column-sorter-up ${isAscend ? 'on' : 'off'}`}
|
||||
type="caret-up"
|
||||
theme="filled"
|
||||
/>
|
||||
<Icon
|
||||
className={`${prefixCls}-column-sorter-down ${isDescend ? 'on' : 'off'}`}
|
||||
type="caret-down"
|
||||
theme="filled"
|
||||
/>
|
||||
{ascend}
|
||||
{descend}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -532,4 +532,59 @@ describe('Table.sorter', () => {
|
||||
.getDOMNode().className,
|
||||
).toContain(' off');
|
||||
});
|
||||
|
||||
it('should first sort by descend, then ascend, then cancel sort', () => {
|
||||
const wrapper = mount(
|
||||
createTable({
|
||||
sortDirections: ['descend', 'ascend'],
|
||||
}),
|
||||
);
|
||||
|
||||
// descend
|
||||
wrapper.find('.ant-table-column-sorters').simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Tom', 'Lucy', 'Jack', 'Jerry']);
|
||||
|
||||
// ascend
|
||||
wrapper.find('.ant-table-column-sorters').simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack', 'Jerry', 'Lucy', 'Tom']);
|
||||
|
||||
// cancel sort
|
||||
wrapper.find('.ant-table-column-sorters').simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
|
||||
});
|
||||
|
||||
it('should first sort by descend, then cancel sort', () => {
|
||||
const wrapper = mount(
|
||||
createTable({
|
||||
sortDirections: ['descend'],
|
||||
}),
|
||||
);
|
||||
|
||||
// descend
|
||||
wrapper.find('.ant-table-column-sorters').simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Tom', 'Lucy', 'Jack', 'Jerry']);
|
||||
|
||||
// cancel sort
|
||||
wrapper.find('.ant-table-column-sorters').simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
|
||||
});
|
||||
|
||||
it('should first sort by descend, then cancel sort. (column prop)', () => {
|
||||
const wrapper = mount(
|
||||
createTable(
|
||||
{},
|
||||
{
|
||||
sortDirections: ['descend'],
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// descend
|
||||
wrapper.find('.ant-table-column-sorters').simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Tom', 'Lucy', 'Jack', 'Jerry']);
|
||||
|
||||
// cancel sort
|
||||
wrapper.find('.ant-table-column-sorters').simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
|
||||
});
|
||||
});
|
||||
|
@ -9172,23 +9172,6 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-table-column-sorter"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-caret-up ant-table-column-sorter-up off"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="caret-up"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
<i
|
||||
class="anticon anticon-caret-down ant-table-column-sorter-down off"
|
||||
>
|
||||
|
@ -11,6 +11,8 @@ title:
|
||||
|
||||
对某一列数据进行排序,通过指定列的 `sorter` 函数即可启动排序按钮。`sorter: function(rowA, rowB) { ... }`, rowA、rowB 为比较的两个行数据。
|
||||
|
||||
`sortDirections: ['ascend' | 'descend']`改变每列可用的排序方式,切换排序时按数组内容依次切换,设置在table props上时对所有列生效。
|
||||
|
||||
使用 `defaultSortOrder` 属性,设置列的默认排序顺序。
|
||||
|
||||
## en-US
|
||||
@ -19,6 +21,8 @@ Use `filters` to generate filter menu in columns, `onFilter` to determine filter
|
||||
|
||||
Use `sorter` to make a column sortable. `sorter` can be a function of the type `function(a, b) { ... }` for sorting data locally.
|
||||
|
||||
`sortDirections: ['ascend' | 'descend']` defines available sort methods for each columns, effective for all columns when set on table props.
|
||||
|
||||
Uses `defaultSortOrder` to make a column sorted by default.
|
||||
|
||||
If a `sortOrder` or `defaultSortOrder` is specified with the value `ascend` or `descend`, you can access this value from within the function passed to the `sorter` as explained above. Such a function can take the form: `function(a, b, sortOrder) { ... }`.
|
||||
@ -50,6 +54,7 @@ const columns = [{
|
||||
// here is that finding the name started with `value`
|
||||
onFilter: (value, record) => record.name.indexOf(value) === 0,
|
||||
sorter: (a, b) => a.name.length - b.name.length,
|
||||
sortDirections: ['descend'],
|
||||
}, {
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
@ -68,6 +73,7 @@ const columns = [{
|
||||
filterMultiple: false,
|
||||
onFilter: (value, record) => record.address.indexOf(value) === 0,
|
||||
sorter: (a, b) => a.address.length - b.address.length,
|
||||
sortDirections: ['descend', 'ascend'],
|
||||
}];
|
||||
|
||||
const data = [{
|
||||
|
@ -41,6 +41,7 @@ export interface ColumnProps<T> {
|
||||
onCellClick?: (record: T, event: any) => void;
|
||||
onCell?: (record: T, rowIndex: number) => any;
|
||||
onHeaderCell?: (props: ColumnProps<T>) => any;
|
||||
sortDirections?: SortOrder[];
|
||||
}
|
||||
|
||||
export interface AdditionalCellProps {
|
||||
@ -162,6 +163,7 @@ export interface TableProps<T> {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
children?: React.ReactNode;
|
||||
sortDirections: SortOrder[];
|
||||
}
|
||||
|
||||
export interface TableStateFilters {
|
||||
|
Loading…
Reference in New Issue
Block a user