Skip to content

Commit

Permalink
✨ Flipping table to automatically scroll to the top
Browse files Browse the repository at this point in the history
👌 apply it in handleFilter and toggleSortOrder
👌 ref instead of findDOMNode
✅ update test for scroll to first row

close #18623
  • Loading branch information
MrHeer committed Sep 25, 2019
1 parent 53b3c5a commit 5395a28
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 8 deletions.
23 changes: 19 additions & 4 deletions components/table/Table.tsx
@@ -1,6 +1,5 @@
/* eslint-disable prefer-spread */
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import omit from 'omit.js';
import RcTable, { INTERNAL_COL_DEFINE } from 'rc-table';
import * as PropTypes from 'prop-types';
Expand All @@ -14,6 +13,7 @@ import Column from './Column';
import ColumnGroup from './ColumnGroup';
import createBodyRow from './createBodyRow';
import { flatArray, treeMap, flatFilter, normalizeColumns } from './util';
import scrollTo from '../_util/scrollTo';
import {
TableProps,
TableSize,
Expand Down Expand Up @@ -136,8 +136,11 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<

row: React.ComponentType<any>;

rcTable: React.RefObject<any>;

constructor(props: TableProps<T>) {
super(props);
this.rcTable = React.createRef();

const { expandedRowRender, columns = [] } = props;

Expand Down Expand Up @@ -498,11 +501,21 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<

generatePopupContainerFunc = (getPopupContainer: TableProps<T>['getPopupContainer']) => {
const { scroll } = this.props;
const table = this.rcTable.current;
if (getPopupContainer) {
return getPopupContainer;
}
// Use undefined to let rc component use default logic.
return scroll ? () => ReactDOM.findDOMNode(this) as HTMLElement : undefined;
return scroll && table ? () => table.tableNode : undefined;
};

scrollToFirstRow = () => {
const { scroll } = this.props;
if (scroll && scroll.scrollToFirstRowOnChange !== false) {
scrollTo(0, {
getContainer: () => this.rcTable.current.bodyTable,
});
}
};

handleFilter = (column: ColumnProps<T>, nextFilters: string[]) => {
Expand Down Expand Up @@ -556,6 +569,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
}

this.setState(newState, () => {
this.scrollToFirstRow();
this.store.setState({
selectionDirty: false,
});
Expand Down Expand Up @@ -747,7 +761,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
current: this.state.pagination.current,
};
}
this.setState(newState);
this.setState(newState, () => this.scrollToFirstRow());

this.store.setState({
selectionDirty: false,
Expand Down Expand Up @@ -823,7 +837,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<

// Controlled
if (this.getSortOrderColumns().length === 0) {
this.setState(newState);
this.setState(newState, () => this.scrollToFirstRow());
}

const { onChange } = this.props;
Expand Down Expand Up @@ -1258,6 +1272,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<

return (
<RcTable
ref={this.rcTable}
key="table"
expandIcon={this.renderExpandIcon(prefixCls)}
{...restProps}
Expand Down
10 changes: 10 additions & 0 deletions components/table/__tests__/Table.pagination.test.js
Expand Up @@ -70,6 +70,16 @@ describe('Table.pagination', () => {
expect(renderedNames(wrapper)).toEqual(['Jack']);
});

// TODO
it('should scroll to first row when page change', () => {
const wrapper = mount(createTable({ scroll: { y: 20 } }));

wrapper
.find('Pager')
.last()
.simulate('click');
});

it('fires change event', () => {
const handleChange = jest.fn();
const handlePaginationChange = jest.fn();
Expand Down
2 changes: 1 addition & 1 deletion components/table/index.en-US.md
Expand Up @@ -79,7 +79,7 @@ const columns = [
| rowClassName | Row's className | Function(record, index):string | - | |
| rowKey | Row's unique key, could be a string or function that returns a string | string\|Function(record):string | `key` | |
| rowSelection | Row selection [config](#rowSelection) | object | null | |
| scroll | Set horizontal or vertical scrolling, can also be used to specify the width and height of the scroll area, could be number, percent value, `true` and ['max-content'](https://developer.mozilla.org/en-US/docs/Web/CSS/width) | { x: number \| true, y: number } | - | |
| scroll | Set horizontal or vertical scrolling, can also be used to specify the width and height of the scroll area, could be number, percent value, `true` and ['max-content'](https://developer.mozilla.org/en-US/docs/Web/CSS/width) | { x: number \| true, y: number, scrollToFirstRowOnChange: boolean } | - | |
| showHeader | Whether to show table header | boolean | `true` | |
| size | Size of table | `default` \| `middle` \| `small` | `default` | |
| title | Table title renderer | Function(currentPageData) | | |
Expand Down
4 changes: 2 additions & 2 deletions components/table/index.zh-CN.md
Expand Up @@ -84,7 +84,7 @@ const columns = [
| rowClassName | 表格行的类名 | Function(record, index):string | - | |
| rowKey | 表格行 key 的取值,可以是字符串或一个函数 | string\|Function(record):string | 'key' | |
| rowSelection | 表格行是否可选择,[配置项](#rowSelection) | object | null | |
| scroll | 设置横向或纵向滚动,也可用于指定滚动区域的宽和高,可以设置为像素值,百分比,`true`['max-content'](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width#max-content) | { x: number \| true, y: number } | - | |
| scroll | 设置横向或纵向滚动,也可用于指定滚动区域的宽和高,可以设置为像素值,百分比,`true`['max-content'](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width#max-content) | { x: number \| true, y: number, scrollToFirstRowOnChange: boolean } | - | |
| showHeader | 是否显示表头 | boolean | true | |
| size | 表格大小 | default \| middle \| small | default | |
| title | 表格标题 | Function(currentPageData) | | |
Expand Down Expand Up @@ -143,7 +143,7 @@ const columns = [
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - | |
| sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `'ascend'` `'descend'` `false` | boolean\|string | - | |
| sortDirections | 支持的排序方式,取值为 `'ascend'` `'descend'` | Array | `['ascend', 'descend']` | 3.15.2 |
| title | 列头显示文字(函数用法 `3.10.0` 后支持) | ReactNode\|({ sortOrder, filters }) => ReactNode | - | |
| title | 列头显示文字(函数用法 `3.10.0` 后支持) | ReactNode\|({ sortOrder, filters }) => ReactNode | - | |
| width | 列宽度([指定了也不生效?](https://github.com/ant-design/ant-design/issues/13825#issuecomment-449889241)| string\|number | - | |
| onCell | 设置单元格属性 | Function(record, rowIndex) | - | |
| onFilter | 本地模式下,确定筛选的运行函数 | Function | - | |
Expand Down
6 changes: 5 additions & 1 deletion components/table/interface.tsx
Expand Up @@ -187,7 +187,11 @@ export interface TableProps<T> {
showHeader?: boolean;
footer?: (currentPageData: T[]) => React.ReactNode;
title?: (currentPageData: T[]) => React.ReactNode;
scroll?: { x?: boolean | number | string; y?: boolean | number | string };
scroll?: {
x?: boolean | number | string;
y?: boolean | number | string;
scrollToFirstRowOnChange?: boolean;
};
childrenColumnName?: string;
bodyStyle?: React.CSSProperties;
className?: string;
Expand Down

0 comments on commit 5395a28

Please sign in to comment.