fix: support table getPopupContainer on row selections (#22787)

* fix: support table getPopupContainer on row selections

* move top to before right

* Add cursor to dropdown arrow

* Feedback suggestion

Co-Authored-By: 偏右 <afc163@gmail.com>

Co-authored-by: Michael Shing <mshing@datto.com>
Co-authored-by: 偏右 <afc163@gmail.com>
This commit is contained in:
Michael Shing 2020-04-01 10:14:53 +01:00 committed by GitHub
parent dba1e5afa6
commit 06f29d0caa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 705 additions and 12 deletions

View File

@ -132,7 +132,7 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
};
const expandType: ExpandType = React.useMemo<ExpandType>(() => {
if (rawData.some((item) => (item as any)[childrenColumnName])) {
if (rawData.some(item => (item as any)[childrenColumnName])) {
return 'nest';
}
@ -320,6 +320,7 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
childrenColumnName,
locale: tableLocale,
expandIconColumnIndex: mergedExpandable.expandIconColumnIndex,
getPopupContainer,
});
const internalRowClassName = (record: RecordType, index: number, indent: number) => {
@ -385,8 +386,8 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
/>
);
if (mergedPagination.position !== null && Array.isArray(mergedPagination.position)) {
const topPos = mergedPagination.position.find((p) => p.indexOf('top') !== -1);
const bottomPos = mergedPagination.position.find((p) => p.indexOf('bottom') !== -1);
const topPos = mergedPagination.position.find(p => p.indexOf('top') !== -1);
const bottomPos = mergedPagination.position.find(p => p.indexOf('bottom') !== -1);
if (!topPos && !bottomPos) {
bottomPaginationNode = renderPagination();
} else {
@ -422,7 +423,7 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
<div
className={wrapperClassNames}
style={style}
onTouchMove={(e) => {
onTouchMove={e => {
e.preventDefault();
}}
>

View File

@ -3,6 +3,7 @@ import { mount, render } from 'enzyme';
import Table from '..';
import Checkbox from '../../checkbox';
import { resetWarned } from '../../_util/warning';
import ConfigProvider from '../../config-provider';
describe('Table.rowSelection', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
@ -567,9 +568,7 @@ describe('Table.rowSelection', () => {
indexList.forEach(index => {
wrapper.find('.ant-dropdown-menu-item .ant-checkbox-wrapper').at(index).simulate('click');
});
wrapper
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
}
function clickItem() {
@ -742,4 +741,39 @@ describe('Table.rowSelection', () => {
expect(onRowClick).not.toHaveBeenCalled();
});
it('should support getPopupContainer', () => {
const rowSelection = {
selections: true,
};
const getPopupContainer = jest.fn(node => node);
const wrapper = mount(
createTable({
rowSelection,
getPopupContainer,
}),
);
jest.useFakeTimers();
wrapper.find('.ant-dropdown-trigger').simulate('mouseenter');
jest.runAllTimers();
expect(wrapper.render()).toMatchSnapshot();
expect(getPopupContainer).toHaveBeenCalled();
});
it('should support getPopupContainer from ConfigProvider', () => {
const rowSelection = {
selections: true,
};
const wrapper = mount(
<ConfigProvider getPopupContainer={node => node.parentNode}>
{createTable({
rowSelection,
})}
</ConfigProvider>,
);
jest.useFakeTimers();
wrapper.find('.ant-dropdown-trigger').simulate('mouseenter');
jest.runAllTimers();
expect(wrapper.render()).toMatchSnapshot();
});
});

View File

@ -892,6 +892,660 @@ exports[`Table.rowSelection render with default selection correctly 1`] = `
</div>
`;
exports[`Table.rowSelection should support getPopupContainer 1`] = `
<div
class="ant-table-wrapper"
>
<div
class="ant-spin-nested-loading"
>
<div
class="ant-spin-container"
>
<div
class="ant-table"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
>
<table
style="table-layout: auto;"
>
<colgroup>
<col
style="width: 60px; min-width: 60px;"
/>
</colgroup>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"
>
<div
class="ant-table-selection"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<div
class="ant-table-selection-extra"
>
<span
class="ant-dropdown-trigger ant-dropdown-open"
>
<span
aria-label="down"
class="anticon anticon-down"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
<div
style="position: absolute; top: 0px; left: 0px; width: 100%;"
/>
</span>
<div>
<div
class="ant-dropdown"
style="opacity: 0;"
>
<ul
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
role="menu"
tabindex="0"
>
<li
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
role="menuitem"
>
Select all data
</li>
<li
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
role="menuitem"
>
Invert current page
</li>
</ul>
</div>
</div>
</div>
</div>
</th>
<th
class="ant-table-cell"
>
Name
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="0"
>
<td
class="ant-table-cell ant-table-selection-column"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Jack
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
>
<td
class="ant-table-cell ant-table-selection-column"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Lucy
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
>
<td
class="ant-table-cell ant-table-selection-column"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Tom
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
>
<td
class="ant-table-cell ant-table-selection-column"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Jerry
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination ant-table-pagination-right"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
tabindex="0"
title="1"
>
<a>
1
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Table.rowSelection should support getPopupContainer from ConfigProvider 1`] = `
<div
class="ant-table-wrapper"
>
<div
class="ant-spin-nested-loading"
>
<div
class="ant-spin-container"
>
<div
class="ant-table"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
>
<table
style="table-layout: auto;"
>
<colgroup>
<col
style="width: 60px; min-width: 60px;"
/>
</colgroup>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"
>
<div
class="ant-table-selection"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<div
class="ant-table-selection-extra"
>
<span
class="ant-dropdown-trigger ant-dropdown-open"
>
<span
aria-label="down"
class="anticon anticon-down"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
<div>
<div
class="ant-dropdown"
style="opacity: 0;"
>
<ul
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
role="menu"
tabindex="0"
>
<li
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
role="menuitem"
>
Select all data
</li>
<li
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
role="menuitem"
>
Invert current page
</li>
</ul>
</div>
</div>
<div
style="position: absolute; top: 0px; left: 0px; width: 100%;"
/>
</div>
</div>
</th>
<th
class="ant-table-cell"
>
Name
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="0"
>
<td
class="ant-table-cell ant-table-selection-column"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Jack
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
>
<td
class="ant-table-cell ant-table-selection-column"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Lucy
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
>
<td
class="ant-table-cell ant-table-selection-column"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Tom
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
>
<td
class="ant-table-cell ant-table-selection-column"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
value=""
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Jerry
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination ant-table-pagination-right"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
tabindex="0"
title="1"
>
<a>
1
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Table.rowSelection use column as selection column when key is \`selection-column\` 1`] = `
<div
class="ant-table-wrapper"

View File

@ -15,6 +15,7 @@ import {
SelectionItem,
TransformColumns,
ExpandType,
GetPopupContainer,
} from '../interface';
const EMPTY_LIST: any[] = [];
@ -37,6 +38,7 @@ interface UseSelectionConfig<RecordType> {
childrenColumnName: string;
expandIconColumnIndex?: number;
locale: TableLocale;
getPopupContainer?: GetPopupContainer;
}
type INTERNAL_SELECTION_ITEM = SelectionItem | typeof SELECTION_ALL | typeof SELECTION_INVERT;
@ -89,6 +91,7 @@ export default function useSelection<RecordType>(
childrenColumnName,
locale: tableLocale,
expandIconColumnIndex,
getPopupContainer,
} = config;
const [innerSelectedKeys, setInnerSelectedKeys] = React.useState<Key[]>();
@ -257,7 +260,7 @@ export default function useSelection<RecordType>(
let customizeSelections: React.ReactNode;
if (mergedSelections) {
const menu = (
<Menu>
<Menu getPopupContainer={getPopupContainer}>
{mergedSelections.map((selection, index) => {
const { key, text, onSelect: onSelectionClick } = selection;
return (
@ -277,7 +280,7 @@ export default function useSelection<RecordType>(
);
customizeSelections = (
<div className={`${prefixCls}-selection-extra`}>
<Dropdown overlay={menu}>
<Dropdown overlay={menu} getPopupContainer={getPopupContainer}>
<span>
<DownOutlined />
</span>

View File

@ -358,9 +358,10 @@
&-extra {
position: absolute;
top: 50%;
right: 0;
transform: translate(100%, -50%);
top: 0;
right: -10px;
cursor: pointer;
transition: all .3s;
.@{iconfont-css-prefix} {
.iconfont-size-under-12px(10px);