mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-10 19:19:20 +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) {
|
renderColumnsDropdown(columns: ColumnProps<T>[], locale: TableLocale) {
|
||||||
const { prefixCls, dropdownPrefixCls } = this.props;
|
const { prefixCls, dropdownPrefixCls } = this.props;
|
||||||
const { sortOrder } = this.state;
|
const { sortOrder } = this.state;
|
||||||
return treeMap(columns, (originColumn, i) => {
|
return treeMap(columns, (column, i) => {
|
||||||
let column = { ...originColumn };
|
const key = this.getColumnKey(column, i) as string;
|
||||||
let key = this.getColumnKey(column, i) as string;
|
|
||||||
let filterDropdown;
|
let filterDropdown;
|
||||||
let sortButton;
|
let sortButton;
|
||||||
|
const isSortColumn = this.isSortColumn(column);
|
||||||
if ((column.filters && column.filters.length > 0) || column.filterDropdown) {
|
if ((column.filters && column.filters.length > 0) || column.filterDropdown) {
|
||||||
let colFilters = this.state.filters[key] || [];
|
let colFilters = this.state.filters[key] || [];
|
||||||
filterDropdown = (
|
filterDropdown = (
|
||||||
@ -780,51 +780,64 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
|||||||
prefixCls={`${prefixCls}-filter`}
|
prefixCls={`${prefixCls}-filter`}
|
||||||
dropdownPrefixCls={dropdownPrefixCls || 'ant-dropdown'}
|
dropdownPrefixCls={dropdownPrefixCls || 'ant-dropdown'}
|
||||||
getPopupContainer={this.getPopupContainer}
|
getPopupContainer={this.getPopupContainer}
|
||||||
|
key="filter-dropdown"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (column.sorter) {
|
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 isAscend = isSortColumn && sortOrder === 'ascend';
|
||||||
const isDescend = isSortColumn && sortOrder === 'descend';
|
const isDescend = isSortColumn && sortOrder === 'descend';
|
||||||
sortButton = (
|
sortButton = (
|
||||||
<div className={`${prefixCls}-column-sorter`}>
|
<div className={`${prefixCls}-column-sorter`} key="sorter">
|
||||||
<span
|
<Icon
|
||||||
className={`${prefixCls}-column-sorter-up ${isAscend ? 'on' : 'off'}`}
|
className={`${prefixCls}-column-sorter-up ${isAscend ? 'on' : 'off'}`}
|
||||||
title="↑"
|
title="↑"
|
||||||
onClick={() => this.toggleSortOrder('ascend', column)}
|
type="caret-up"
|
||||||
>
|
theme="filled"
|
||||||
<Icon type="caret-up" />
|
/>
|
||||||
</span>
|
<Icon
|
||||||
<span
|
|
||||||
className={`${prefixCls}-column-sorter-down ${isDescend ? 'on' : 'off'}`}
|
className={`${prefixCls}-column-sorter-down ${isDescend ? 'on' : 'off'}`}
|
||||||
title="↓"
|
title="↓"
|
||||||
onClick={() => this.toggleSortOrder('descend', column)}
|
type="caret-down"
|
||||||
>
|
theme="filled"
|
||||||
<Icon type="caret-down" />
|
/>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
column.title = (
|
return {
|
||||||
<span key={key}>
|
...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}
|
{column.title}
|
||||||
{sortButton}
|
{sortButton}
|
||||||
{filterDropdown}
|
</div>,
|
||||||
</span>
|
filterDropdown,
|
||||||
);
|
],
|
||||||
|
onHeaderCell: (columnProps: ColumnProps<T>) => {
|
||||||
if (sortButton || filterDropdown) {
|
// for onHeaderCell compatibility
|
||||||
column.className = classNames(`${prefixCls}-column-has-filters`, column.className);
|
const headerCellProps = column.onHeaderCell ? column.onHeaderCell(columnProps) : {};
|
||||||
|
return {
|
||||||
|
onClick: (e: MouseEvent) => {
|
||||||
|
this.handleColumnHeaderClick(e);
|
||||||
|
if (headerCellProps && headerCellProps.onClick) {
|
||||||
|
headerCellProps.onClick(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...headerCellProps,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return column;
|
handleColumnHeaderClick = (e: MouseEvent) => {
|
||||||
});
|
console.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShowSizeChange = (current: number, pageSize: number) => {
|
handleShowSizeChange = (current: number, pageSize: number) => {
|
||||||
|
@ -11,6 +11,13 @@ import Radio from '../radio';
|
|||||||
import FilterDropdownMenuWrapper from './FilterDropdownMenuWrapper';
|
import FilterDropdownMenuWrapper from './FilterDropdownMenuWrapper';
|
||||||
import { FilterMenuProps, FilterMenuState, ColumnProps, ColumnFilterItem } from './interface';
|
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> {
|
export default class FilterMenu<T> extends React.Component<FilterMenuProps<T>, FilterMenuState> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
handleFilter() {},
|
handleFilter() {},
|
||||||
@ -181,12 +188,14 @@ export default class FilterMenu<T> extends React.Component<FilterMenuProps<T>, F
|
|||||||
return filterIcon ? React.cloneElement(filterIcon as any, {
|
return filterIcon ? React.cloneElement(filterIcon as any, {
|
||||||
title: locale.filterTitle,
|
title: locale.filterTitle,
|
||||||
className: classNames(`${prefixCls}-icon`, filterIcon.props.className),
|
className: classNames(`${prefixCls}-icon`, filterIcon.props.className),
|
||||||
|
onClick: stopPropagation,
|
||||||
}) : (
|
}) : (
|
||||||
<Icon
|
<Icon
|
||||||
title={locale.filterTitle}
|
title={locale.filterTitle}
|
||||||
type="filter"
|
type="filter"
|
||||||
theme="filled"
|
theme="filled"
|
||||||
className={dropdownSelectedClass}
|
className={dropdownSelectedClass}
|
||||||
|
onClick={stopPropagation}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -47,37 +47,86 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: @table-header-icon-color;
|
color: @table-header-icon-color;
|
||||||
transition: all .3s;
|
transition: all .3s;
|
||||||
width: 24px;
|
width: 28px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: @text-color-secondary;
|
|
||||||
background: rgba(0, 0, 0, .04);
|
|
||||||
}
|
|
||||||
|
|
||||||
> svg {
|
> svg {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-top: -@font-size-sm / 2;
|
margin-top: -@font-size-sm / 2 + 1px;
|
||||||
margin-left: -@font-size-sm / 2;
|
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 {
|
.@{table-prefix-cls}-filter-selected.@{iconfont-css-prefix}-filter {
|
||||||
color: @primary-color;
|
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;
|
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 {
|
&-bordered {
|
||||||
.@{table-prefix-cls}-header > table,
|
.@{table-prefix-cls}-header > table,
|
||||||
.@{table-prefix-cls}-body > table,
|
.@{table-prefix-cls}-body > table,
|
||||||
|
Loading…
Reference in New Issue
Block a user