From 6f67c435c2411543d13e66cc37487f2df1b9d7e5 Mon Sep 17 00:00:00 2001 From: afc163 Date: Mon, 17 Sep 2018 17:33:02 +0800 Subject: [PATCH] separate filter and sort into two click area --- components/table/Table.tsx | 79 +++++++++------- components/table/filterDropdown.tsx | 9 ++ components/table/style/index.less | 139 ++++++++++++---------------- 3 files changed, 116 insertions(+), 111 deletions(-) diff --git a/components/table/Table.tsx b/components/table/Table.tsx index 959bee2f8f..7686decf30 100755 --- a/components/table/Table.tsx +++ b/components/table/Table.tsx @@ -764,11 +764,11 @@ export default class Table extends React.Component, TableState< renderColumnsDropdown(columns: ColumnProps[], 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 extends React.Component, 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 = ( -
- + this.toggleSortOrder('ascend', column)} - > - - - + this.toggleSortOrder('descend', column)} - > - - + type="caret-down" + theme="filled" + />
); } - column.title = ( - - {column.title} - {sortButton} - {filterDropdown} - - ); - - 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: [ +
+ {column.title} + {sortButton} +
, + filterDropdown, + ], + onHeaderCell: (columnProps: ColumnProps) => { + // 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); diff --git a/components/table/filterDropdown.tsx b/components/table/filterDropdown.tsx index 80eae441c2..a58960dbae 100755 --- a/components/table/filterDropdown.tsx +++ b/components/table/filterDropdown.tsx @@ -11,6 +11,13 @@ import Radio from '../radio'; import FilterDropdownMenuWrapper from './FilterDropdownMenuWrapper'; import { FilterMenuProps, FilterMenuState, ColumnProps, ColumnFilterItem } from './interface'; +function stopPropagation(e: React.SyntheticEvent) { + e.stopPropagation(); + if (e.nativeEvent.stopImmediatePropagation) { + e.nativeEvent.stopImmediatePropagation(); + } +} + export default class FilterMenu extends React.Component, FilterMenuState> { static defaultProps = { handleFilter() {}, @@ -181,12 +188,14 @@ export default class FilterMenu extends React.Component, F return filterIcon ? React.cloneElement(filterIcon as any, { title: locale.filterTitle, className: classNames(`${prefixCls}-icon`, filterIcon.props.className), + onClick: stopPropagation, }) : ( ); } diff --git a/components/table/style/index.less b/components/table/style/index.less index 46dd5bef91..e8489062e8 100644 --- a/components/table/style/index.less +++ b/components/table/style/index.less @@ -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,