mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-30 11:08:45 +08:00
separate filter and sort into two click area
This commit is contained in:
parent
4c84dad106
commit
6f67c435c2
@ -764,11 +764,11 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
renderColumnsDropdown(columns: ColumnProps<T>[], locale: TableLocale) {
|
||||
const { prefixCls, dropdownPrefixCls } = this.props;
|
||||
const { sortOrder } = this.state;
|
||||
return treeMap(columns, (originColumn, i) => {
|
||||
let column = { ...originColumn };
|
||||
let key = this.getColumnKey(column, i) as string;
|
||||
return treeMap(columns, (column, i) => {
|
||||
const key = this.getColumnKey(column, i) as string;
|
||||
let filterDropdown;
|
||||
let sortButton;
|
||||
const isSortColumn = this.isSortColumn(column);
|
||||
if ((column.filters && column.filters.length > 0) || column.filterDropdown) {
|
||||
let colFilters = this.state.filters[key] || [];
|
||||
filterDropdown = (
|
||||
@ -780,53 +780,66 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
prefixCls={`${prefixCls}-filter`}
|
||||
dropdownPrefixCls={dropdownPrefixCls || 'ant-dropdown'}
|
||||
getPopupContainer={this.getPopupContainer}
|
||||
key="filter-dropdown"
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (column.sorter) {
|
||||
let isSortColumn = this.isSortColumn(column);
|
||||
if (isSortColumn) {
|
||||
column.className = classNames(column.className, {
|
||||
[`${prefixCls}-column-sort`]: sortOrder,
|
||||
});
|
||||
}
|
||||
const isAscend = isSortColumn && sortOrder === 'ascend';
|
||||
const isDescend = isSortColumn && sortOrder === 'descend';
|
||||
sortButton = (
|
||||
<div className={`${prefixCls}-column-sorter`}>
|
||||
<span
|
||||
<div className={`${prefixCls}-column-sorter`} key="sorter">
|
||||
<Icon
|
||||
className={`${prefixCls}-column-sorter-up ${isAscend ? 'on' : 'off'}`}
|
||||
title="↑"
|
||||
onClick={() => this.toggleSortOrder('ascend', column)}
|
||||
>
|
||||
<Icon type="caret-up" />
|
||||
</span>
|
||||
<span
|
||||
type="caret-up"
|
||||
theme="filled"
|
||||
/>
|
||||
<Icon
|
||||
className={`${prefixCls}-column-sorter-down ${isDescend ? 'on' : 'off'}`}
|
||||
title="↓"
|
||||
onClick={() => this.toggleSortOrder('descend', column)}
|
||||
>
|
||||
<Icon type="caret-down" />
|
||||
</span>
|
||||
type="caret-down"
|
||||
theme="filled"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
column.title = (
|
||||
<span key={key}>
|
||||
{column.title}
|
||||
{sortButton}
|
||||
{filterDropdown}
|
||||
</span>
|
||||
);
|
||||
|
||||
if (sortButton || filterDropdown) {
|
||||
column.className = classNames(`${prefixCls}-column-has-filters`, column.className);
|
||||
}
|
||||
|
||||
return column;
|
||||
return {
|
||||
...column,
|
||||
className: classNames(column.className, {
|
||||
[`${prefixCls}-column-has-actions`]: sortButton || filterDropdown,
|
||||
[`${prefixCls}-column-has-filters`]: filterDropdown,
|
||||
[`${prefixCls}-column-has-sorters`]: sortButton,
|
||||
[`${prefixCls}-column-sort`]: isSortColumn && sortOrder,
|
||||
}),
|
||||
title: [
|
||||
<div key="sort-area" className={`${prefixCls}-column-sorters`}>
|
||||
{column.title}
|
||||
{sortButton}
|
||||
</div>,
|
||||
filterDropdown,
|
||||
],
|
||||
onHeaderCell: (columnProps: ColumnProps<T>) => {
|
||||
// for onHeaderCell compatibility
|
||||
const headerCellProps = column.onHeaderCell ? column.onHeaderCell(columnProps) : {};
|
||||
return {
|
||||
onClick: (e: MouseEvent) => {
|
||||
this.handleColumnHeaderClick(e);
|
||||
if (headerCellProps && headerCellProps.onClick) {
|
||||
headerCellProps.onClick(e);
|
||||
}
|
||||
},
|
||||
...headerCellProps,
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
handleColumnHeaderClick = (e: MouseEvent) => {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
handleShowSizeChange = (current: number, pageSize: number) => {
|
||||
const pagination = this.state.pagination;
|
||||
pagination.onShowSizeChange!(current, pageSize);
|
||||
|
@ -11,6 +11,13 @@ import Radio from '../radio';
|
||||
import FilterDropdownMenuWrapper from './FilterDropdownMenuWrapper';
|
||||
import { FilterMenuProps, FilterMenuState, ColumnProps, ColumnFilterItem } from './interface';
|
||||
|
||||
function stopPropagation(e: React.SyntheticEvent<any>) {
|
||||
e.stopPropagation();
|
||||
if (e.nativeEvent.stopImmediatePropagation) {
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
|
||||
export default class FilterMenu<T> extends React.Component<FilterMenuProps<T>, FilterMenuState> {
|
||||
static defaultProps = {
|
||||
handleFilter() {},
|
||||
@ -181,12 +188,14 @@ export default class FilterMenu<T> extends React.Component<FilterMenuProps<T>, F
|
||||
return filterIcon ? React.cloneElement(filterIcon as any, {
|
||||
title: locale.filterTitle,
|
||||
className: classNames(`${prefixCls}-icon`, filterIcon.props.className),
|
||||
onClick: stopPropagation,
|
||||
}) : (
|
||||
<Icon
|
||||
title={locale.filterTitle}
|
||||
type="filter"
|
||||
theme="filled"
|
||||
className={dropdownSelectedClass}
|
||||
onClick={stopPropagation}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -47,37 +47,86 @@
|
||||
cursor: pointer;
|
||||
color: @table-header-icon-color;
|
||||
transition: all .3s;
|
||||
width: 24px;
|
||||
width: 28px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
color: @text-color-secondary;
|
||||
background: rgba(0, 0, 0, .04);
|
||||
}
|
||||
|
||||
> svg {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -@font-size-sm / 2;
|
||||
margin-top: -@font-size-sm / 2 + 1px;
|
||||
margin-left: -@font-size-sm / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.@{table-prefix-cls}-column-sorter + .@{iconfont-css-prefix}-filter {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.@{table-prefix-cls}-filter-selected.@{iconfont-css-prefix}-filter {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
&.@{table-prefix-cls}-column-has-filters {
|
||||
.@{table-prefix-cls}-column-sorter {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
width: 14px;
|
||||
height: @font-size-base;
|
||||
margin-top: -@font-size-base / 2;
|
||||
text-align: center;
|
||||
color: @table-header-icon-color;
|
||||
|
||||
&-up,
|
||||
&-down {
|
||||
.iconfont-size-under-12px(8px);
|
||||
line-height: 4px;
|
||||
height: 4px;
|
||||
transition: all .3s;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&-down {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&.@{table-prefix-cls}-column-has-actions {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
// Very complicated styles logic but neccessary
|
||||
&:hover {
|
||||
background: #f5f5f5;
|
||||
.@{iconfont-css-prefix}-filter,
|
||||
.@{table-prefix-cls}-filter-icon {
|
||||
background: #f5f5f5;
|
||||
&:hover {
|
||||
color: @text-color-secondary;
|
||||
background: #ebebeb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{table-prefix-cls}-column-sorters {
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: transparent;
|
||||
transition: all .3s;
|
||||
}
|
||||
&:hover:before {
|
||||
background: rgba(0, 0, 0, .04);
|
||||
}
|
||||
}
|
||||
|
||||
&.@{table-prefix-cls}-column-has-filters .@{table-prefix-cls}-column-sorter {
|
||||
right: 28px + 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,72 +287,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-column-sorter {
|
||||
position: relative;
|
||||
margin-left: 8px;
|
||||
display: inline-block;
|
||||
vertical-align: text-bottom;
|
||||
top: -1.5px;
|
||||
width: 14px;
|
||||
height: @font-size-base;
|
||||
text-align: center;
|
||||
font-weight: normal;
|
||||
color: @table-header-icon-color;
|
||||
|
||||
&-up,
|
||||
&-down {
|
||||
display: block;
|
||||
width: 14px;
|
||||
height: @font-size-base / 2 - 1px;
|
||||
line-height: @font-size-base / 2 - 1px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
&:hover .@{iconfont-css-prefix} {
|
||||
color: @primary-4;
|
||||
}
|
||||
&.on {
|
||||
.@{iconfont-css-prefix}-caret-up,
|
||||
.@{iconfont-css-prefix}-caret-down {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
height: 30px;
|
||||
width: 14px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-up:after {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&-down:after {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.@{iconfont-css-prefix}-caret-up,
|
||||
.@{iconfont-css-prefix}-caret-down {
|
||||
.iconfont-size-under-12px(8px);
|
||||
line-height: 4px;
|
||||
height: 4px;
|
||||
transition: all .3s;
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&-down {
|
||||
margin-top: 1.5px;
|
||||
}
|
||||
|
||||
.@{iconfont-css-prefix}-caret-up {
|
||||
margin-top: 0.5px;
|
||||
}
|
||||
}
|
||||
|
||||
&-bordered {
|
||||
.@{table-prefix-cls}-header > table,
|
||||
.@{table-prefix-cls}-body > table,
|
||||
|
Loading…
Reference in New Issue
Block a user