From 297f3e0c4fdcbd7ab5a10ba290fe3dd379b9348e Mon Sep 17 00:00:00 2001 From: AllenFang Date: Sat, 8 Dec 2018 16:25:59 +0800 Subject: [PATCH] implement SizePerPageDropdownStandalone --- .../react-bootstrap-table2-paginator/index.js | 3 +- .../src/page-resolver.js | 2 +- .../src/pagination-handler.js | 1 - .../src/size-per-page-dropdown-adapter.js | 63 ++++++++ .../src/size-per-page-dropdown-standalone.js | 12 ++ .../test/page-resolver.test.js | 2 - .../test/pagination.test.js | 1 - .../size-per-page-dropdown-adapter.test.js | 146 ++++++++++++++++++ 8 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-adapter.js create mode 100644 packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-standalone.js create mode 100644 packages/react-bootstrap-table2-paginator/test/size-per-page-dropdown-adapter.test.js diff --git a/packages/react-bootstrap-table2-paginator/index.js b/packages/react-bootstrap-table2-paginator/index.js index b399ffa..1956416 100644 --- a/packages/react-bootstrap-table2-paginator/index.js +++ b/packages/react-bootstrap-table2-paginator/index.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import createBaseContext from './src/state-context'; import createDataContext from './src/data-context'; import PaginationListStandalone from './src/pagination-list-standalone'; +import SizePerPageDropdownStandalone from './src/size-per-page-dropdown-standalone'; export default (options = {}) => ({ createContext: createDataContext, @@ -22,4 +23,4 @@ CustomizableProvider.propTypes = { }; export const PaginationProvider = CustomizableProvider; -export { PaginationListStandalone }; +export { PaginationListStandalone, SizePerPageDropdownStandalone }; diff --git a/packages/react-bootstrap-table2-paginator/src/page-resolver.js b/packages/react-bootstrap-table2-paginator/src/page-resolver.js index 3c17e93..cb77b17 100644 --- a/packages/react-bootstrap-table2-paginator/src/page-resolver.js +++ b/packages/react-bootstrap-table2-paginator/src/page-resolver.js @@ -11,7 +11,7 @@ export default ExtendBase => initialState() { const totalPages = this.calculateTotalPage(); const lastPage = this.calculateLastPage(totalPages); - return { totalPages, lastPage, dropdownOpen: false }; + return { totalPages, lastPage }; } calculateTotalPage(sizePerPage = this.props.currSizePerPage, dataSize = this.props.dataSize) { diff --git a/packages/react-bootstrap-table2-paginator/src/pagination-handler.js b/packages/react-bootstrap-table2-paginator/src/pagination-handler.js index 1ffc973..fcc9e11 100644 --- a/packages/react-bootstrap-table2-paginator/src/pagination-handler.js +++ b/packages/react-bootstrap-table2-paginator/src/pagination-handler.js @@ -31,7 +31,6 @@ export default WrappedComponent => if (currPage > newLastPage) currPage = newLastPage; onSizePerPageChange(selectedSize, currPage); } - this.closeDropDown(); } handleChangePage(newPage) { diff --git a/packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-adapter.js b/packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-adapter.js new file mode 100644 index 0000000..88ad6c8 --- /dev/null +++ b/packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-adapter.js @@ -0,0 +1,63 @@ +/* eslint react/prop-types: 0 */ +import React, { Component } from 'react'; + +import pageResolver from './page-resolver'; + +export default WrappedComponent => + class SizePerPageDropdownAdapter extends pageResolver(Component) { + constructor(props) { + super(props); + this.closeDropDown = this.closeDropDown.bind(this); + this.toggleDropDown = this.toggleDropDown.bind(this); + this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this); + this.state = { dropdownOpen: false }; + } + + toggleDropDown() { + const dropdownOpen = !this.state.dropdownOpen; + this.setState(() => ({ dropdownOpen })); + } + + closeDropDown() { + this.setState(() => ({ dropdownOpen: false })); + } + + handleChangeSizePerPage(sizePerPage) { + this.props.onSizePerPageChange(sizePerPage); + this.closeDropDown(); + } + + render() { + const { + sizePerPageList, + currSizePerPage, + hideSizePerPage, + sizePerPageRenderer, + sizePerPageOptionRenderer + } = this.props; + const { dropdownOpen: open } = this.state; + + if (sizePerPageList.length > 1 && !hideSizePerPage) { + if (sizePerPageRenderer) { + return sizePerPageRenderer({ + options: this.calculateSizePerPageStatus(), + currSizePerPage: `${currSizePerPage}`, + onSizePerPageChange: this.handleChangeSizePerPage + }); + } + return ( + + ); + } + return null; + } + }; + diff --git a/packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-standalone.js b/packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-standalone.js new file mode 100644 index 0000000..48ed0b1 --- /dev/null +++ b/packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-standalone.js @@ -0,0 +1,12 @@ +import React from 'react'; +import SizePerPageDropdown from './size-per-page-dropdown'; +import standaloneAdapter from './standalone-adapter'; +import paginationHandler from './pagination-handler'; +import sizePerPageDropdownAdapter from './size-per-page-dropdown-adapter'; + +const SizePerPageDropdownStandalone = props => ( + +); + +export default +standaloneAdapter(paginationHandler(sizePerPageDropdownAdapter(SizePerPageDropdownStandalone))); diff --git a/packages/react-bootstrap-table2-paginator/test/page-resolver.test.js b/packages/react-bootstrap-table2-paginator/test/page-resolver.test.js index 1a030b9..ca31da5 100644 --- a/packages/react-bootstrap-table2-paginator/test/page-resolver.test.js +++ b/packages/react-bootstrap-table2-paginator/test/page-resolver.test.js @@ -46,8 +46,6 @@ describe('PageResolver', () => { expect(instance.state.lastPage).toBeDefined(); expect(instance.state.lastPage).toEqual( instance.calculateLastPage(instance.state.totalPages)); - expect(instance.state.dropdownOpen).toBeDefined(); - expect(instance.state.dropdownOpen).toBeFalsy(); }); }); diff --git a/packages/react-bootstrap-table2-paginator/test/pagination.test.js b/packages/react-bootstrap-table2-paginator/test/pagination.test.js index 29c04b5..6091e31 100644 --- a/packages/react-bootstrap-table2-paginator/test/pagination.test.js +++ b/packages/react-bootstrap-table2-paginator/test/pagination.test.js @@ -68,7 +68,6 @@ describe('Pagination', () => { expect(sizePerPageDropDown.prop('options')).toEqual(instance.calculateSizePerPageStatus()); expect(sizePerPageDropDown.prop('onSizePerPageChange')).toEqual(instance.handleChangeSizePerPage); expect(sizePerPageDropDown.prop('onClick')).toEqual(instance.toggleDropDown); - expect(sizePerPageDropDown.prop('open')).toEqual(instance.state.dropdownOpen); }); }); diff --git a/packages/react-bootstrap-table2-paginator/test/size-per-page-dropdown-adapter.test.js b/packages/react-bootstrap-table2-paginator/test/size-per-page-dropdown-adapter.test.js new file mode 100644 index 0000000..2a45cfb --- /dev/null +++ b/packages/react-bootstrap-table2-paginator/test/size-per-page-dropdown-adapter.test.js @@ -0,0 +1,146 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import sizePerPageDropdownAdapter from '../src/size-per-page-dropdown-adapter'; + + +const MockComponent = () => null; + +const SizePerPageDropdownAdapter = sizePerPageDropdownAdapter(MockComponent); +describe('sizePerPageDropdownAdapter', () => { + let wrapper; + let instance; + + const createMockProps = props => ({ + dataSize: 100, + sizePerPageList: [10, 20, 30, 50], + currPage: 1, + currSizePerPage: 10, + alwaysShowAllBtns: false, + onSizePerPageChange: jest.fn(), + hidePageListOnlyOnePage: false, + hideSizePerPage: false, + optionRenderer: jest.fn(), + sizePerPageOptionRenderer: jest.fn(), + ...props + }); + + describe('render', () => { + const props = createMockProps(); + beforeEach(() => { + wrapper = shallow(); + instance = wrapper.instance(); + }); + + it('should render successfully', () => { + const mockComponent = wrapper.find(MockComponent); + expect(mockComponent).toHaveLength(1); + + expect(mockComponent.props().currSizePerPage).toEqual(`${props.currSizePerPage}`); + expect(mockComponent.props().options).toBeDefined(); + expect(mockComponent.props().optionRenderer).toBeDefined(); + expect(mockComponent.props().onSizePerPageChange).toEqual(instance.handleChangeSizePerPage); + expect(mockComponent.props().onClick).toEqual(instance.toggleDropDown); + expect(mockComponent.props().onBlur).toEqual(instance.closeDropDown); + expect(mockComponent.props().open).toEqual(instance.state.dropdownOpen); + }); + }); + + describe('when props.sizePerPageList is empty array', () => { + beforeEach(() => { + const props = createMockProps({ sizePerPageList: [] }); + wrapper = shallow(); + instance = wrapper.instance(); + }); + + it('should not render component', () => { + const sizePerPageDropDown = wrapper.find(MockComponent); + expect(sizePerPageDropDown.length).toBe(0); + }); + }); + + describe('when props.hideSizePerPage is true', () => { + beforeEach(() => { + const props = createMockProps({ hideSizePerPage: true }); + wrapper = shallow(); + instance = wrapper.instance(); + }); + + it('should not rendering SizePerPageDropDown component', () => { + const sizePerPageDropDown = wrapper.find(MockComponent); + expect(sizePerPageDropDown.length).toBe(0); + }); + }); + + describe('toggleDropDown', () => { + beforeEach(() => { + const props = createMockProps(); + wrapper = shallow(); + instance = wrapper.instance(); + }); + + it('should set state.dropdownOpen as true when it is false', () => { + instance.toggleDropDown(); + expect(instance.state.dropdownOpen).toBeTruthy(); + }); + + it('should set state.dropdownOpen as false when it is true', () => { + instance.toggleDropDown(); + instance.toggleDropDown(); + expect(instance.state.dropdownOpen).toBeFalsy(); + }); + }); + + describe('closeDropDown', () => { + beforeEach(() => { + const props = createMockProps(); + wrapper = shallow(); + instance = wrapper.instance(); + }); + + it('should always set state.dropdownOpen as false', () => { + instance.closeDropDown(); + expect(instance.state.dropdownOpen).toBeFalsy(); + instance.closeDropDown(); + expect(instance.state.dropdownOpen).toBeFalsy(); + }); + }); + + describe('handleChangeSizePerPage', () => { + let props; + const sizePerPage = 25; + beforeEach(() => { + props = createMockProps(); + wrapper = shallow(); + instance = wrapper.instance(); + instance.handleChangeSizePerPage(sizePerPage); + }); + + it('should call props.onSizePerPageChange correctly', () => { + expect(props.onSizePerPageChange).toHaveBeenCalledTimes(1); + expect(props.onSizePerPageChange).toHaveBeenCalledWith(sizePerPage); + }); + + it('should always set state.dropdownOpen as false', () => { + expect(instance.state.dropdownOpen).toBeFalsy(); + }); + }); + + describe('when props.sizePerPageRenderer is defined', () => { + const sizePerPageRenderer = jest.fn().mockReturnValue(null); + + beforeEach(() => { + sizePerPageRenderer.mockClear(); + const props = createMockProps({ sizePerPageRenderer }); + wrapper = shallow(); + instance = wrapper.instance(); + }); + + it('should not render default component', () => { + expect(wrapper.find(MockComponent)).toHaveLength(0); + }); + + it('should call props.sizePerPageRenderer correctly', () => { + expect(sizePerPageRenderer).toHaveBeenCalledTimes(1); + }); + }); +});