style: redesign Table header action (#30651)

* feat: improve Table filter and sorter position

* fix: edge cases of th border

* fix lint

* style: apply new design

* fix css detail

* fix stylelint

* fix css error

* style: sorter icon hover color

* fix test cases

* update snapshot

* fix th padding

* fix calc

* style: fix dark theme
This commit is contained in:
afc163 2021-05-24 22:16:06 +08:00 committed by GitHub
parent aa5990fb21
commit 082f626a3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 3209 additions and 3981 deletions

View File

@ -310,6 +310,7 @@
@table-header-bg: #1d1d1d; @table-header-bg: #1d1d1d;
@table-body-sort-bg: fade(@white, 1%); @table-body-sort-bg: fade(@white, 1%);
@table-row-hover-bg: #262626; @table-row-hover-bg: #262626;
@table-header-cell-split-color: fade(@white, 8%);
@table-header-sort-bg: #262626; @table-header-sort-bg: #262626;
@table-header-filter-active-bg: #434343; @table-header-filter-active-bg: #434343;
@table-header-sort-active-bg: #303030; @table-header-sort-active-bg: #303030;

View File

@ -609,11 +609,12 @@
@table-font-size: @font-size-base; @table-font-size: @font-size-base;
@table-font-size-md: @table-font-size; @table-font-size-md: @table-font-size;
@table-font-size-sm: @table-font-size; @table-font-size-sm: @table-font-size;
@table-header-cell-split-color: rgba(0, 0, 0, 0.06);
// Sorter // Sorter
// Legacy: `table-header-sort-active-bg` is used for hover not real active // Legacy: `table-header-sort-active-bg` is used for hover not real active
@table-header-sort-active-bg: darken(@table-header-bg, 3%); @table-header-sort-active-bg: rgba(0, 0, 0, 0.04);
// Filter // Filter
@table-header-filter-active-bg: darken(@table-header-sort-active-bg, 5%); @table-header-filter-active-bg: rgba(0, 0, 0, 0.04);
@table-filter-btns-bg: inherit; @table-filter-btns-bg: inherit;
@table-filter-dropdown-bg: @component-background; @table-filter-dropdown-bg: @component-background;
@table-expand-icon-bg: @component-background; @table-expand-icon-bg: @component-background;

View File

@ -182,15 +182,14 @@ describe('Table.sorter', () => {
jest.useFakeTimers(); jest.useFakeTimers();
const wrapper = mount(createTable({})); const wrapper = mount(createTable({}));
// default show sorter tooltip // default show sorter tooltip
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseenter'); wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
jest.runAllTimers(); jest.runAllTimers();
wrapper.update(); wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy(); expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseout'); wrapper.find('.ant-table-column-sorters').simulate('mouseout');
// set table props showSorterTooltip is false // set table props showSorterTooltip is false
wrapper.setProps({ showSorterTooltip: false }); wrapper.setProps({ showSorterTooltip: false });
expect(wrapper.find('.ant-table-column-sorters-with-tooltip')).toHaveLength(0);
jest.runAllTimers(); jest.runAllTimers();
wrapper.update(); wrapper.update();
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0); expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);
@ -199,17 +198,16 @@ describe('Table.sorter', () => {
showSorterTooltip: false, showSorterTooltip: false,
columns: [{ ...column, showSorterTooltip: true }], columns: [{ ...column, showSorterTooltip: true }],
}); });
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseenter'); wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
jest.runAllTimers(); jest.runAllTimers();
wrapper.update(); wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy(); expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseout'); wrapper.find('.ant-table-column-sorters').simulate('mouseout');
// set table props showSorterTooltip is true, column showSorterTooltip is false // set table props showSorterTooltip is true, column showSorterTooltip is false
wrapper.setProps({ wrapper.setProps({
showSorterTooltip: true, showSorterTooltip: true,
columns: [{ ...column, showSorterTooltip: false }], columns: [{ ...column, showSorterTooltip: false }],
}); });
expect(wrapper.find('.ant-table-column-sorters-with-tooltip')).toHaveLength(0);
jest.runAllTimers(); jest.runAllTimers();
wrapper.update(); wrapper.update();
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0); expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);
@ -221,14 +219,13 @@ describe('Table.sorter', () => {
const wrapper = mount( const wrapper = mount(
createTable({ showSorterTooltip: { placement: 'bottom', title: 'static title' } }), createTable({ showSorterTooltip: { placement: 'bottom', title: 'static title' } }),
); );
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseenter'); wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
jest.runAllTimers(); jest.runAllTimers();
wrapper.update(); wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy(); expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseout'); wrapper.find('.ant-table-column-sorters').simulate('mouseout');
wrapper.setProps({ showSorterTooltip: false }); wrapper.setProps({ showSorterTooltip: false });
expect(wrapper.find('.ant-table-column-sorters-with-tooltip')).toHaveLength(0);
jest.runAllTimers(); jest.runAllTimers();
wrapper.update(); wrapper.update();
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0); expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);
@ -236,16 +233,15 @@ describe('Table.sorter', () => {
showSorterTooltip: false, showSorterTooltip: false,
columns: [{ ...column, showSorterTooltip: true }], columns: [{ ...column, showSorterTooltip: true }],
}); });
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseenter'); wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
jest.runAllTimers(); jest.runAllTimers();
wrapper.update(); wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy(); expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseout'); wrapper.find('.ant-table-column-sorters').simulate('mouseout');
wrapper.setProps({ wrapper.setProps({
showSorterTooltip: true, showSorterTooltip: true,
columns: [{ ...column, showSorterTooltip: false }], columns: [{ ...column, showSorterTooltip: false }],
}); });
expect(wrapper.find('.ant-table-column-sorters-with-tooltip')).toHaveLength(0);
jest.runAllTimers(); jest.runAllTimers();
wrapper.update(); wrapper.update();
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0); expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);

View File

@ -67,23 +67,15 @@ exports[`Table.filter renders custom filter icon as ReactNode 1`] = `
<div <div
class="ant-table-filter-column" class="ant-table-filter-column"
> >
Name
<span <span
class="ant-table-filter-column-title" class="ant-dropdown-trigger ant-table-filter-trigger"
> role="button"
Name tabindex="-1"
</span>
<span
class="ant-table-filter-trigger-container"
> >
<span <span
class="ant-dropdown-trigger ant-table-filter-trigger" class="customize-icon"
role="button" />
tabindex="-1"
>
<span
class="customize-icon"
/>
</span>
</span> </span>
</div> </div>
</th> </th>
@ -175,21 +167,13 @@ exports[`Table.filter renders custom filter icon as string correctly 1`] = `
<div <div
class="ant-table-filter-column" class="ant-table-filter-column"
> >
Name
<span <span
class="ant-table-filter-column-title" class="ant-dropdown-trigger ant-table-filter-trigger"
role="button"
tabindex="-1"
> >
Name string
</span>
<span
class="ant-table-filter-trigger-container"
>
<span
class="ant-dropdown-trigger ant-table-filter-trigger"
role="button"
tabindex="-1"
>
string
</span>
</span> </span>
</div> </div>
</th> </th>
@ -297,49 +281,41 @@ exports[`Table.filter renders custom filter icon with right Tooltip title 1`] =
<div <div
class="ant-table-filter-column" class="ant-table-filter-column"
> >
Name
<span <span
class="ant-table-filter-column-title" class="ant-dropdown-trigger ant-table-filter-trigger"
> role="button"
Name tabindex="-1"
</span>
<span
class="ant-table-filter-trigger-container"
> >
<span <span
class="ant-dropdown-trigger ant-table-filter-trigger" class="ant-tooltip-open"
role="button"
tabindex="-1"
> >
<span Tooltip
class="ant-tooltip-open" </span>
<div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast"
style="opacity: 0; pointer-events: none;"
> >
Tooltip
</span>
<div>
<div <div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast" class="ant-tooltip-content"
style="opacity: 0; pointer-events: none;"
> >
<div <div
class="ant-tooltip-content" class="ant-tooltip-arrow"
> >
<div <span
class="ant-tooltip-arrow" class="ant-tooltip-arrow-content"
> />
<span </div>
class="ant-tooltip-arrow-content" <div
/> class="ant-tooltip-inner"
</div> role="tooltip"
<div >
class="ant-tooltip-inner" title
role="tooltip"
>
title
</div>
</div> </div>
</div> </div>
</div> </div>
</span> </div>
</span> </span>
</div> </div>
</th> </th>
@ -431,38 +407,30 @@ exports[`Table.filter renders filter correctly 1`] = `
<div <div
class="ant-table-filter-column" class="ant-table-filter-column"
> >
Name
<span <span
class="ant-table-filter-column-title" class="ant-dropdown-trigger ant-table-filter-trigger"
> role="button"
Name tabindex="-1"
</span>
<span
class="ant-table-filter-trigger-container"
> >
<span <span
class="ant-dropdown-trigger ant-table-filter-trigger" aria-label="filter"
role="button" class="anticon anticon-filter"
tabindex="-1" role="img"
> >
<span <svg
aria-label="filter" aria-hidden="true"
class="anticon anticon-filter" data-icon="filter"
role="img" fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
> >
<svg <path
aria-hidden="true" d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"
data-icon="filter" />
fill="currentColor" </svg>
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"
/>
</svg>
</span>
</span> </span>
</span> </span>
</div> </div>
@ -559,157 +527,149 @@ exports[`Table.filter should support getPopupContainer 1`] = `
<div <div
class="ant-table-filter-column" class="ant-table-filter-column"
> >
Name
<span <span
class="ant-table-filter-column-title" class="ant-dropdown-trigger ant-table-filter-trigger"
> role="button"
Name tabindex="-1"
</span>
<span
class="ant-table-filter-trigger-container ant-table-filter-trigger-container-open"
> >
<span <span
class="ant-dropdown-trigger ant-table-filter-trigger" aria-label="filter"
role="button" class="anticon anticon-filter"
tabindex="-1" role="img"
> >
<span <svg
aria-label="filter" aria-hidden="true"
class="anticon anticon-filter" data-icon="filter"
role="img" fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
> >
<svg <path
aria-hidden="true" d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"
data-icon="filter" />
fill="currentColor" </svg>
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"
/>
</svg>
</span>
</span> </span>
<div> </span>
<div>
<div
class="ant-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
style="opacity: 0; pointer-events: none;"
>
<div <div
class="ant-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up" class="ant-table-filter-dropdown"
style="opacity: 0; pointer-events: none;"
> >
<div <ul
class="ant-table-filter-dropdown" class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
data-menu-list="true"
role="menu"
tabindex="0"
> >
<ul <li
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light" class="ant-dropdown-menu-item"
data-menu-list="true" data-menu-id="rc-menu-uuid-test-boy"
role="menu" role="menuitem"
tabindex="0" tabindex="-1"
> >
<li <label
class="ant-dropdown-menu-item" class="ant-checkbox-wrapper"
data-menu-id="rc-menu-uuid-test-boy"
role="menuitem"
tabindex="-1"
> >
<label <span
class="ant-checkbox-wrapper" class="ant-checkbox"
> >
<span <input
class="ant-checkbox" class="ant-checkbox-input"
> type="checkbox"
<input value=""
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span>
Boy
</span>
</li>
<li
class="ant-dropdown-menu-item"
data-menu-id="rc-menu-uuid-test-girl"
role="menuitem"
tabindex="-1"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span>
Girl
</span>
</li>
<li
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
role="none"
>
<div
aria-controls="rc-menu-uuid-test-title-popup"
aria-expanded="false"
aria-haspopup="true"
class="ant-dropdown-menu-submenu-title"
data-menu-id="rc-menu-uuid-test-title"
role="menuitem"
tabindex="-1"
title="Title"
>
Title
<i
class="ant-dropdown-menu-submenu-arrow"
/> />
</div> <span
</li> class="ant-checkbox-inner"
</ul> />
<div </span>
class="ant-table-filter-dropdown-btns" </label>
<span>
Boy
</span>
</li>
<li
class="ant-dropdown-menu-item"
data-menu-id="rc-menu-uuid-test-girl"
role="menuitem"
tabindex="-1"
> >
<button <label
class="ant-btn ant-btn-link ant-btn-sm" class="ant-checkbox-wrapper"
disabled=""
type="button"
> >
<span> <span
Reset class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span> </span>
</button> </label>
<button <span>
class="ant-btn ant-btn-primary ant-btn-sm" Girl
type="button" </span>
</li>
<li
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
role="none"
>
<div
aria-controls="rc-menu-uuid-test-title-popup"
aria-expanded="false"
aria-haspopup="true"
class="ant-dropdown-menu-submenu-title"
data-menu-id="rc-menu-uuid-test-title"
role="menuitem"
tabindex="-1"
title="Title"
> >
<span> Title
OK <i
</span> class="ant-dropdown-menu-submenu-arrow"
</button> />
</div> </div>
</li>
</ul>
<div
class="ant-table-filter-dropdown-btns"
>
<button
class="ant-btn ant-btn-link ant-btn-sm"
disabled=""
type="button"
>
<span>
Reset
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<span>
OK
</span>
</button>
</div> </div>
</div> </div>
</div> </div>
<div </div>
style="position: absolute; top: 0px; left: 0px; width: 100%;" <div
/> style="position: absolute; top: 0px; left: 0px; width: 100%;"
<div />
style="position: absolute; top: 0px; left: 0px; width: 100%;" <div
/> style="position: absolute; top: 0px; left: 0px; width: 100%;"
</span> />
</div> </div>
</th> </th>
</tr> </tr>
@ -800,157 +760,149 @@ exports[`Table.filter should support getPopupContainer from ConfigProvider 1`] =
<div <div
class="ant-table-filter-column" class="ant-table-filter-column"
> >
Name
<span <span
class="ant-table-filter-column-title" class="ant-dropdown-trigger ant-table-filter-trigger"
> role="button"
Name tabindex="-1"
</span>
<span
class="ant-table-filter-trigger-container ant-table-filter-trigger-container-open"
> >
<span <span
class="ant-dropdown-trigger ant-table-filter-trigger" aria-label="filter"
role="button" class="anticon anticon-filter"
tabindex="-1" role="img"
> >
<span <svg
aria-label="filter" aria-hidden="true"
class="anticon anticon-filter" data-icon="filter"
role="img" fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
> >
<svg <path
aria-hidden="true" d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"
data-icon="filter" />
fill="currentColor" </svg>
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"
/>
</svg>
</span>
</span> </span>
<div> </span>
<div>
<div
class="ant-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up"
style="opacity: 0; pointer-events: none;"
>
<div <div
class="ant-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up" class="ant-table-filter-dropdown"
style="opacity: 0; pointer-events: none;"
> >
<div <ul
class="ant-table-filter-dropdown" class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
data-menu-list="true"
role="menu"
tabindex="0"
> >
<ul <li
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light" class="ant-dropdown-menu-item"
data-menu-list="true" data-menu-id="rc-menu-uuid-test-boy"
role="menu" role="menuitem"
tabindex="0" tabindex="-1"
> >
<li <label
class="ant-dropdown-menu-item" class="ant-checkbox-wrapper"
data-menu-id="rc-menu-uuid-test-boy"
role="menuitem"
tabindex="-1"
> >
<label <span
class="ant-checkbox-wrapper" class="ant-checkbox"
> >
<span <input
class="ant-checkbox" class="ant-checkbox-input"
> type="checkbox"
<input value=""
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span>
Boy
</span>
</li>
<li
class="ant-dropdown-menu-item"
data-menu-id="rc-menu-uuid-test-girl"
role="menuitem"
tabindex="-1"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span>
Girl
</span>
</li>
<li
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
role="none"
>
<div
aria-controls="rc-menu-uuid-test-title-popup"
aria-expanded="false"
aria-haspopup="true"
class="ant-dropdown-menu-submenu-title"
data-menu-id="rc-menu-uuid-test-title"
role="menuitem"
tabindex="-1"
title="Title"
>
Title
<i
class="ant-dropdown-menu-submenu-arrow"
/> />
</div> <span
</li> class="ant-checkbox-inner"
</ul> />
<div </span>
class="ant-table-filter-dropdown-btns" </label>
<span>
Boy
</span>
</li>
<li
class="ant-dropdown-menu-item"
data-menu-id="rc-menu-uuid-test-girl"
role="menuitem"
tabindex="-1"
> >
<button <label
class="ant-btn ant-btn-link ant-btn-sm" class="ant-checkbox-wrapper"
disabled=""
type="button"
> >
<span> <span
Reset class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span> </span>
</button> </label>
<button <span>
class="ant-btn ant-btn-primary ant-btn-sm" Girl
type="button" </span>
</li>
<li
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
role="none"
>
<div
aria-controls="rc-menu-uuid-test-title-popup"
aria-expanded="false"
aria-haspopup="true"
class="ant-dropdown-menu-submenu-title"
data-menu-id="rc-menu-uuid-test-title"
role="menuitem"
tabindex="-1"
title="Title"
> >
<span> Title
OK <i
</span> class="ant-dropdown-menu-submenu-arrow"
</button> />
</div> </div>
</li>
</ul>
<div
class="ant-table-filter-dropdown-btns"
>
<button
class="ant-btn ant-btn-link ant-btn-sm"
disabled=""
type="button"
>
<span>
Reset
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<span>
OK
</span>
</button>
</div> </div>
</div> </div>
</div> </div>
<div </div>
style="position: absolute; top: 0px; left: 0px; width: 100%;" <div
/> style="position: absolute; top: 0px; left: 0px; width: 100%;"
<div />
style="position: absolute; top: 0px; left: 0px; width: 100%;" <div
/> style="position: absolute; top: 0px; left: 0px; width: 100%;"
</span> />
</div> </div>
</th> </th>
</tr> </tr>

View File

@ -9,61 +9,57 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
class="ant-table-cell ant-table-column-has-sorters" class="ant-table-cell ant-table-column-has-sorters"
> >
<div <div
class="ant-table-column-sorters-with-tooltip" class="ant-table-column-sorters"
> >
<div <span>
class="ant-table-column-sorters" Name
</span>
<span
class="ant-table-column-sorter ant-table-column-sorter-full"
> >
<span>
Name
</span>
<span <span
class="ant-table-column-sorter ant-table-column-sorter-full" class="ant-table-column-sorter-inner"
> >
<span <span
class="ant-table-column-sorter-inner" aria-label="caret-up"
class="anticon anticon-caret-up ant-table-column-sorter-up"
role="img"
> >
<span <svg
aria-label="caret-up" aria-hidden="true"
class="anticon anticon-caret-up ant-table-column-sorter-up" data-icon="caret-up"
role="img" fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
> >
<svg <path
aria-hidden="true" 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"
data-icon="caret-up" />
fill="currentColor" </svg>
focusable="false" </span>
height="1em" <span
viewBox="0 0 1024 1024" aria-label="caret-down"
width="1em" class="anticon anticon-caret-down ant-table-column-sorter-down"
> role="img"
<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
/> aria-hidden="true"
</svg> data-icon="caret-down"
</span> fill="currentColor"
<span focusable="false"
aria-label="caret-down" height="1em"
class="anticon anticon-caret-down ant-table-column-sorter-down" viewBox="0 0 1024 1024"
role="img" width="1em"
> >
<svg <path
aria-hidden="true" d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
data-icon="caret-down" />
fill="currentColor" </svg>
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
/>
</svg>
</span>
</span> </span>
</span> </span>
</div> </span>
</div> </div>
</th> </th>
</tr> </tr>
@ -101,61 +97,57 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
class="ant-table-cell ant-table-column-sort ant-table-column-has-sorters" class="ant-table-cell ant-table-column-sort ant-table-column-has-sorters"
> >
<div <div
class="ant-table-column-sorters-with-tooltip" class="ant-table-column-sorters"
> >
<div <span>
class="ant-table-column-sorters" Age
</span>
<span
class="ant-table-column-sorter ant-table-column-sorter-full"
> >
<span>
Age
</span>
<span <span
class="ant-table-column-sorter ant-table-column-sorter-full" class="ant-table-column-sorter-inner"
> >
<span <span
class="ant-table-column-sorter-inner" aria-label="caret-up"
class="anticon anticon-caret-up ant-table-column-sorter-up active"
role="img"
> >
<span <svg
aria-label="caret-up" aria-hidden="true"
class="anticon anticon-caret-up ant-table-column-sorter-up active" data-icon="caret-up"
role="img" fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
> >
<svg <path
aria-hidden="true" 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"
data-icon="caret-up" />
fill="currentColor" </svg>
focusable="false" </span>
height="1em" <span
viewBox="0 0 1024 1024" aria-label="caret-down"
width="1em" class="anticon anticon-caret-down ant-table-column-sorter-down"
> role="img"
<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
/> aria-hidden="true"
</svg> data-icon="caret-down"
</span> fill="currentColor"
<span focusable="false"
aria-label="caret-down" height="1em"
class="anticon anticon-caret-down ant-table-column-sorter-down" viewBox="0 0 1024 1024"
role="img" width="1em"
> >
<svg <path
aria-hidden="true" d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
data-icon="caret-down" />
fill="currentColor" </svg>
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
/>
</svg>
</span>
</span> </span>
</span> </span>
</div> </span>
</div> </div>
</th> </th>
</tr> </tr>

File diff suppressed because it is too large Load Diff

View File

@ -152,6 +152,8 @@ class App extends React.Component {
dataIndex: 'address', dataIndex: 'address',
key: 'address', key: 'address',
...this.getColumnSearchProps('address'), ...this.getColumnSearchProps('address'),
sorter: (a, b) => a.address.length - b.address.length,
sortDirections: ['descend', 'ascend'],
}, },
]; ];
return <Table columns={columns} dataSource={data} />; return <Table columns={columns} dataSource={data} />;

View File

@ -85,10 +85,7 @@ const columns = [
value: 'New York', value: 'New York',
}, },
], ],
filterMultiple: false,
onFilter: (value, record) => record.address.indexOf(value) === 0, onFilter: (value, record) => record.address.indexOf(value) === 0,
sorter: (a, b) => a.address.length - b.address.length,
sortDirections: ['descend', 'ascend'],
}, },
]; ];

View File

@ -282,35 +282,28 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
return ( return (
<div className={classNames(`${prefixCls}-column`)}> <div className={classNames(`${prefixCls}-column`)}>
<span className={`${prefixCls}-column-title`}>{children}</span> {children}
<Dropdown
<span overlay={menu}
className={classNames(`${prefixCls}-trigger-container`, { trigger={['click']}
[`${prefixCls}-trigger-container-open`]: mergedVisible, visible={mergedVisible}
})} onVisibleChange={onVisibleChange}
onClick={e => { getPopupContainer={getPopupContainer}
e.stopPropagation(); placement={direction === 'rtl' ? 'bottomLeft' : 'bottomRight'}
}}
> >
<Dropdown <span
overlay={menu} role="button"
trigger={['click']} tabIndex={-1}
visible={mergedVisible} className={classNames(`${prefixCls}-trigger`, {
onVisibleChange={onVisibleChange} active: filtered,
getPopupContainer={getPopupContainer} })}
placement={direction === 'rtl' ? 'bottomLeft' : 'bottomRight'} onClick={e => {
e.stopPropagation();
}}
> >
<span {filterIcon}
role="button" </span>
tabIndex={-1} </Dropdown>
className={classNames(`${prefixCls}-trigger`, {
active: filtered,
})}
>
{filterIcon}
</span>
</Dropdown>
</span>
</div> </div>
); );
} }

View File

@ -168,9 +168,7 @@ function injectSorter<RecordType>(
</div> </div>
); );
return showSorterTooltip ? ( return showSorterTooltip ? (
<Tooltip {...tooltipProps}> <Tooltip {...tooltipProps}>{renderSortTitle}</Tooltip>
<div className={`${prefixCls}-column-sorters-with-tooltip`}>{renderSortTitle}</div>
</Tooltip>
) : ( ) : (
renderSortTitle renderSortTitle
); );

View File

@ -32,6 +32,12 @@
> tr:not(:last-child) > th { > tr:not(:last-child) > th {
border-bottom: @border-width-base @border-style-base @table-border-color; border-bottom: @border-width-base @border-style-base @table-border-color;
} }
> tr > th {
&::before {
background-color: transparent !important;
}
}
} }
// Fixed right should provides additional border // Fixed right should provides additional border

View File

@ -8,7 +8,6 @@
@descriptions-prefix-cls: ~'@{ant-prefix}-descriptions'; @descriptions-prefix-cls: ~'@{ant-prefix}-descriptions';
@table-header-icon-color: #bfbfbf; @table-header-icon-color: #bfbfbf;
@table-header-icon-color-hover: darken(@table-header-icon-color, 10%); @table-header-icon-color-hover: darken(@table-header-icon-color, 10%);
@table-header-sort-active-filter-bg: lighten(@table-header-sort-active-bg, 2%);
@table-sticky-zindex: (@zindex-table-fixed + 1); @table-sticky-zindex: (@zindex-table-fixed + 1);
@table-sticky-scroll-bar-active-bg: fade(@table-sticky-scroll-bar-bg, 80%); @table-sticky-scroll-bar-active-bg: fade(@table-sticky-scroll-bar-bg, 80%);
@ -79,6 +78,7 @@
&-thead { &-thead {
> tr { > tr {
> th { > th {
position: relative;
color: @table-header-color; color: @table-header-color;
font-weight: 500; font-weight: 500;
text-align: left; text-align: left;
@ -89,6 +89,18 @@
&[colspan]:not([colspan='1']) { &[colspan]:not([colspan='1']) {
text-align: center; text-align: center;
} }
&:not(:last-child):not(.@{table-prefix-cls}-selection-column):not(.@{table-prefix-cls}-row-expand-icon-cell):not([colspan])::before {
position: absolute;
top: 50%;
right: 0;
width: 1px;
height: 1.6em;
background-color: @table-header-cell-split-color;
transform: translateY(-50%);
transition: background-color 0.3s;
content: '';
}
} }
} }
@ -195,47 +207,52 @@
// ============================ Sorter ============================ // ============================ Sorter ============================
&-thead th.@{table-prefix-cls}-column-has-sorters { &-thead th.@{table-prefix-cls}-column-has-sorters {
padding: 0;
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
&:hover { &:hover {
background: @table-header-sort-active-bg; background: @table-header-sort-active-bg;
.@{table-prefix-cls}-filter-trigger-container { &::before {
background: @table-header-sort-active-filter-bg; background-color: transparent !important;
} }
} }
} }
&-thead th.@{table-prefix-cls}-column-sort { &-thead th.@{table-prefix-cls}-column-sort {
background: @table-header-sort-bg; background: @table-header-sort-bg;
&::before {
background-color: transparent !important;
}
} }
td&-column-sort { td&-column-sort {
background: @table-body-sort-bg; background: @table-body-sort-bg;
} }
&-column-sorters-with-tooltip {
display: inline-block;
width: 100%;
}
&-column-sorters { &-column-sorters {
display: inline-flex; display: flex;
flex: auto;
align-items: center; align-items: center;
padding: @table-padding-vertical @table-padding-horizontal; justify-content: space-between;
&::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
content: '';
}
} }
&-column-sorter { &-column-sorter {
margin-top: 0.15em;
margin-bottom: -0.15em;
margin-left: @padding-xs;
color: @table-header-icon-color; color: @table-header-icon-color;
font-size: 0;
&-full { transition: color 0.3s;
margin-top: -0.2em;
margin-bottom: 0;
}
&-inner { &-inner {
display: inline-flex; display: inline-flex;
@ -257,65 +274,31 @@
} }
} }
&-column-sorters:hover &-column-sorter {
color: darken(@table-header-icon-color, 10%);
}
// ============================ Filter ============================ // ============================ Filter ============================
&-filter-column { &-filter-column {
display: flex; display: flex;
align-items: center; justify-content: space-between;
margin: -@table-padding-vertical -@table-padding-horizontal;
}
&-filter-column-title {
flex: auto;
padding: @table-padding-vertical 2.3em @table-padding-vertical @table-padding-horizontal;
}
// Remove padding when sorter also provided
&-thead tr th.@{table-prefix-cls}-column-has-sorters {
.@{table-prefix-cls}-filter-column {
margin: 0;
}
.@{table-prefix-cls}-filter-column-title {
padding: 0 2.3em 0 0;
}
}
&-filter-trigger-container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
display: flex;
flex: none;
align-items: stretch;
align-self: stretch;
cursor: pointer;
transition: background-color 0.3s;
&-open,
&:hover,
.@{table-prefix-cls}-thead th.@{table-prefix-cls}-column-has-sorters:hover &:hover {
background: @table-header-filter-active-bg;
}
} }
&-filter-trigger { &-filter-trigger {
display: block; position: relative;
width: 2.3em; display: flex;
align-items: center;
margin: -4px (-@table-padding-horizontal / 2) -4px 4px;
padding: 0 4px;
color: @table-header-icon-color; color: @table-header-icon-color;
font-size: @font-size-sm; font-size: @font-size-sm;
transition: color 0.3s; border-radius: @border-radius-base;
cursor: pointer;
transition: all 0.3s;
.@{iconfont-css-prefix} {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.@{table-prefix-cls}-filter-trigger-container-open &,
&:hover { &:hover {
color: @text-color-secondary; color: @text-color-secondary;
background: @table-header-filter-active-bg;
} }
&.active { &.active {
@ -388,6 +371,10 @@
} }
} }
table tr th&-selection-column::after {
background-color: transparent !important;
}
&-selection { &-selection {
position: relative; position: relative;
display: inline-flex; display: inline-flex;
@ -564,6 +551,7 @@
content: ''; content: '';
pointer-events: none; pointer-events: none;
} }
&-cell-fix-right-first::after, &-cell-fix-right-first::after,
&-cell-fix-right-last::after { &-cell-fix-right-last::after {
position: absolute; position: absolute;
@ -611,6 +599,10 @@
.@{table-prefix-cls}-cell-fix-left-last::after { .@{table-prefix-cls}-cell-fix-left-last::after {
box-shadow: inset 10px 0 8px -8px darken(@shadow-color, 5%); box-shadow: inset 10px 0 8px -8px darken(@shadow-color, 5%);
} }
.@{table-prefix-cls}-cell-fix-left-last::before {
background-color: transparent !important;
}
} }
&-ping-right { &-ping-right {

View File

@ -13,22 +13,8 @@
padding: @padding-vertical @padding-horizontal; padding: @padding-vertical @padding-horizontal;
} }
.@{table-prefix-cls}-thead { .@{table-prefix-cls}-filter-trigger {
th.@{table-prefix-cls}-column-has-sorters { margin-right: -(@padding-horizontal / 2);
padding: 0;
}
.@{table-prefix-cls}-filter-column {
margin: -@padding-vertical -@padding-horizontal;
}
.@{table-prefix-cls}-filter-column-title {
padding: @padding-vertical 2.3em @padding-vertical @padding-horizontal;
}
.@{table-prefix-cls}-column-sorters {
padding: @padding-vertical @padding-horizontal;
}
} }
.@{table-prefix-cls}-expanded-row-fixed { .@{table-prefix-cls}-expanded-row-fixed {