From 1663bf5c37af8aaefea9a371a0c1aa05e227444f Mon Sep 17 00:00:00 2001 From: nikogu <644506165@qq.com> Date: Wed, 18 Apr 2018 14:10:53 +0800 Subject: [PATCH] List integrate pagination functional fixed: #9303 --- .../__tests__/__snapshots__/demo.test.js.snap | 260 +++++------------- .../__snapshots__/pagination.test.js.snap | 82 ++++++ components/list/__tests__/pagination.test.js | 129 +++++++++ components/list/demo/vertical.md | 16 +- components/list/index.tsx | 82 +++++- 5 files changed, 356 insertions(+), 213 deletions(-) create mode 100644 components/list/__tests__/__snapshots__/pagination.test.js.snap create mode 100644 components/list/__tests__/pagination.test.js diff --git a/components/list/__tests__/__snapshots__/demo.test.js.snap b/components/list/__tests__/__snapshots__/demo.test.js.snap index df54b8902ead..22356c8774f7 100644 --- a/components/list/__tests__/__snapshots__/demo.test.js.snap +++ b/components/list/__tests__/__snapshots__/demo.test.js.snap @@ -1192,198 +1192,6 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = ` -
-
-
-
-
- - - -
-
-

- - ant design part 3 - -

-
- Ant Design, a design language for background applications, is refined by Ant UED Team. -
-
-
-
- We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently. -
-
    -
  • - - - 156 - - -
  • -
  • - - - 156 - - -
  • -
  • - - - 2 - -
  • -
-
-
- logo -
-
-
-
-
-
-
-
- - - -
-
-

- - ant design part 4 - -

-
- Ant Design, a design language for background applications, is refined by Ant UED Team. -
-
-
-
- We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently. -
-
    -
  • - - - 156 - - -
  • -
  • - - - 156 - - -
  • -
  • - - - 2 - -
  • -
-
-
- logo -
-
-
+`; diff --git a/components/list/__tests__/pagination.test.js b/components/list/__tests__/pagination.test.js new file mode 100644 index 000000000000..2858e2baee84 --- /dev/null +++ b/components/list/__tests__/pagination.test.js @@ -0,0 +1,129 @@ +import React from 'react'; +import { render, mount } from 'enzyme'; +import List from '..'; + +describe('List.pagination', () => { + const data = [ + { key: 0, name: 'Jack' }, + { key: 1, name: 'Lucy' }, + { key: 2, name: 'Tom' }, + { key: 3, name: 'Jerry' }, + ]; + + const pagination = { className: 'my-page', pageSize: 2 }; + + function createList(props) { + return ( + ( + + {item.name} + + )} + {...props} + /> + ); + } + + function renderedNames(wrapper) { + return wrapper.find('.ant-list-item-content').map(row => row.text()); + } + + it('renders pagination correctly', () => { + const wrapper = render(createList()); + expect(wrapper).toMatchSnapshot(); + }); + + it('should not show pager if pagination.hideOnSinglePage is true and only 1 page', () => { + const wrapper = mount( + createList({ pagination: { pageSize: 3, hideOnSinglePage: true } }) + ); + expect(wrapper.find('.ant-pagination')).toHaveLength(1); + wrapper.setProps({ pagination: { pageSize: 3, hideOnSinglePage: false } }); + expect(wrapper.find('.ant-pagination')).toHaveLength(1); + wrapper.setProps({ pagination: { pageSize: 4, hideOnSinglePage: true } }); + expect(wrapper.find('.ant-pagination')).toHaveLength(0); + wrapper.setProps({ pagination: { pageSize: 4, hideOnSinglePage: false } }); + expect(wrapper.find('.ant-pagination')).toHaveLength(1); + wrapper.setProps({ pagination: { pageSize: 5, hideOnSinglePage: true } }); + expect(wrapper.find('.ant-pagination')).toHaveLength(0); + wrapper.setProps({ pagination: { pageSize: 5, hideOnSinglePage: false } }); + expect(wrapper.find('.ant-pagination')).toHaveLength(1); + }); + + it('paginate data', () => { + const wrapper = mount(createList()); + + expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy']); + wrapper + .find('Pager') + .last() + .simulate('click'); + expect(renderedNames(wrapper)).toEqual(['Tom', 'Jerry']); + }); + + it('repaginates when pageSize change', () => { + const wrapper = mount(createList()); + + wrapper.setProps({ pagination: { pageSize: 1 } }); + expect(renderedNames(wrapper)).toEqual(['Jack']); + }); + + it('fires change event', () => { + const handlePaginationChange = jest.fn(); + const noop = () => {}; + const wrapper = mount( + createList({ + pagination: { + ...pagination, + onChange: handlePaginationChange, + onShowSizeChange: noop, + }, + }) + ); + + wrapper + .find('Pager') + .last() + .simulate('click'); + + expect(handlePaginationChange).toBeCalledWith(2, 2); + }); + + // https://github.com/ant-design/ant-design/issues/4532 + // https://codepen.io/afc163/pen/pWVRJV?editors=001 + it('should display pagination as prop pagination change between true and false', () => { + const wrapper = mount(createList()); + expect(wrapper.find('.ant-pagination')).toHaveLength(1); + expect(wrapper.find('.ant-pagination-item')).toHaveLength(2); + wrapper.setProps({ pagination: false }); + expect(wrapper.find('.ant-pagination')).toHaveLength(0); + wrapper.setProps({ pagination }); + wrapper.update(); + expect(wrapper.find('.ant-pagination')).toHaveLength(1); + expect(wrapper.find('.ant-pagination-item')).toHaveLength(2); + wrapper.find('.ant-pagination-item-2').simulate('click'); + expect(renderedNames(wrapper)).toEqual(['Tom', 'Jerry']); + wrapper.setProps({ pagination: false }); + expect(wrapper.find('.ant-pagination')).toHaveLength(0); + wrapper.setProps({ pagination: true }); + expect(wrapper.find('.ant-pagination')).toHaveLength(1); + expect(wrapper.find('.ant-pagination-item')).toHaveLength(1); // pageSize will be 10 + expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']); + }); + + // https://github.com/ant-design/ant-design/issues/5259 + it('change to correct page when data source changes', () => { + const wrapper = mount(createList({ pagination: { pageSize: 1 } })); + wrapper.find('.ant-pagination-item-3').simulate('click'); + wrapper.setProps({ dataSource: [data[0]] }); + expect( + wrapper + .find('.ant-pagination-item-1') + .hasClass('ant-pagination-item-active') + ).toBe(true); + }); +}); diff --git a/components/list/demo/vertical.md b/components/list/demo/vertical.md index 277adad9dcba..40b525c5751d 100644 --- a/components/list/demo/vertical.md +++ b/components/list/demo/vertical.md @@ -17,7 +17,7 @@ Setting `itemLayout` property with `vertical` to create a vertical list. import { List, Avatar, Icon } from 'antd'; const listData = []; -for (let i = 0; i < 5; i++) { +for (let i = 0; i < 23; i++) { listData.push({ href: 'http://ant.design', title: `ant design part ${i}`, @@ -27,13 +27,6 @@ for (let i = 0; i < 5; i++) { }); } -const pagination = { - pageSize: 10, - current: 1, - total: listData.length, - onChange: (() => {}), -}; - const IconText = ({ type, text }) => ( @@ -45,7 +38,12 @@ ReactDOM.render( { + console.log(page); + }, + pageSize: 3, + }} dataSource={listData} renderItem={item => ( { pagination: false, }; - private keys: {[key: string]: string} = {}; + state = { + paginationCurrent: 1, + }; + + defaultPaginationProps = { + current: 1, + pageSize: 10, + onChange: (page: number, pageSize: number) => { + const { pagination } = this.props; + this.setState({ + paginationCurrent: page, + }); + if (pagination && pagination.onChange) { + pagination.onChange(page, pageSize); + } + }, + total: 0, + }; + + private keys: { [key: string]: string } = {}; getChildContext() { return { @@ -108,10 +135,15 @@ export default class List extends React.Component { renderEmpty = (contextLocale: ListLocale) => { const locale = { ...contextLocale, ...this.props.locale }; - return
{locale.emptyText}
; + return ( +
+ {locale.emptyText} +
+ ); } render() { + const { paginationCurrent } = this.state; const { bordered, split, @@ -138,7 +170,7 @@ export default class List extends React.Component { spinning: loadingProp, }; } - const isLoading = (loadingProp && loadingProp.spinning); + const isLoading = loadingProp && loadingProp.spinning; // large => lg // small => sm @@ -163,24 +195,54 @@ export default class List extends React.Component { [`${prefixCls}-something-after-last-item`]: this.isSomethingAfterLastItem(), }); + this.defaultPaginationProps.total = dataSource.length; + this.defaultPaginationProps.current = paginationCurrent; + const paginationProps = { ...this.defaultPaginationProps, ...pagination }; + const largestPage = Math.ceil( + paginationProps.total / paginationProps.pageSize, + ); + if (paginationProps.current > largestPage) { + paginationProps.current = largestPage; + } const paginationContent = (
- +
); + let splitDataSource = [...dataSource]; + if (pagination) { + if ( + dataSource.length > + (paginationProps.current - 1) * paginationProps.pageSize + ) { + splitDataSource = [...dataSource].splice( + (paginationProps.current - 1) * paginationProps.pageSize, + paginationProps.pageSize, + ); + } + } + let childrenContent; childrenContent = isLoading &&
; - if (dataSource.length > 0) { - const items = dataSource.map((item: any, index: number) => this.renderItem(item, index)); - const childrenList = React.Children.map(items, (child: any, index) => React.cloneElement(child, { + if (splitDataSource.length > 0) { + const items = splitDataSource.map((item: any, index: number) => + this.renderItem(item, index), + ); + const childrenList = React.Children.map(items, (child: any, index) => + React.cloneElement(child, { key: this.keys[index], }), ); childrenContent = grid ? ( {childrenList} - ) : childrenList; + ) : ( + childrenList + ); } else if (!children && !isLoading) { childrenContent = ( {
{childrenContent} {loadMore} - {(!loadMore && pagination) ? paginationContent : null} + {!loadMore && pagination ? paginationContent : null}
);