From cccebd1449745ee74170de30bfa1b57f3ea80a17 Mon Sep 17 00:00:00 2001 From: "dvv.avinash" Date: Sun, 1 Jul 2018 23:42:11 +0530 Subject: [PATCH] pagination logic is updated, and better READ.me --- README.md | 85 +++++++----- dist/components/ReactPagination.js | 179 +++++++++++++++++--------- package.json | 2 +- src/index.js | 10 +- src/lib/components/ReactPagination.js | 131 +++++++++++-------- 5 files changed, 255 insertions(+), 152 deletions(-) diff --git a/README.md b/README.md index 544d987..93ff138 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,65 @@ -## pagination-with-react +# Project Title +React Pagination -## Installation -Run the following command: -`npm install pagination-with-react` +### Documentation +Props -## Usage - import { ReactPagination } from 'pagination-with-react'; -# Props: -``` - totalItems [required] - numberOfItemsPerPage [required] - numberOfPagesPerScreen [required] - totalNumberOfPages = round(totalItems / numberOfItemsPerPage); [required] - totalScreensNumber = round(totalNumberOfPages / numberOfPagesPerScreen); [required] - onPageButtonClick [required] - currentActiveIndex [required] + Prop | Type +---------|--------- +currentActiveIndex | Number +children | children app +numberOfPagesPerScreen| Number, How many pages numbers should user see per screen? +totalNumberOfPages | Number, Total number of pages +onPageButtonClick| Function, callback function for onClick pagination button to get the current page number +prefix | String or React Component, if you want to add anything before pagination buttons +suffix| String or React Component, if you want to add anything after pagination buttons +icons | Object with keys `left, leftMost, right, rightMost ` if you want to change the icons of a arrow ``` +Icons Default Values +icons: { + left: , + leftMost: , + right: , + rightMost: , +} +``` + -# Basic Example +### Installing + +npm install pagination-with-react ``` - import { ReactPagination } from 'pagination-with-react'; - { - this.setState({ - data, - }) - }} - currentActiveIndex={this.state.id} - > - {this.state.data} - +import React from 'react'; +import ReactDOM from 'react-dom'; +import { ReactPagination } from 'pagination-with-react'; + +class App extends React.Component{ + constructor(){ + super() + this.state={ + id: 1, + } + } + render() { + return ( + { + this.setState({ + id, + }) + console.log(this.state) + }} + currentActiveIndex={this.state.id} + > +

Children {this.state.id}

+
+ ) + } +} ``` \ No newline at end of file diff --git a/dist/components/ReactPagination.js b/dist/components/ReactPagination.js index 71e2181..8c4b95a 100644 --- a/dist/components/ReactPagination.js +++ b/dist/components/ReactPagination.js @@ -2,70 +2,131 @@ import React from 'react'; import times from 'lodash.times'; import classNames from 'classnames'; -class ReactPagination extends React.Component { - constructor(props) { - super(props); - let currentScreenNumber = 1; - const { totalScreensNumber, numberOfPagesPerScreen, currentActiveIndex } = props; - for (let i = 1; i <= totalScreensNumber; i += 1) { - if (i * numberOfPagesPerScreen >= currentActiveIndex) { - currentScreenNumber = i; - break; - } - } - this.state = { - currentScreenNumber - }; - } - render() { - const { - currentActiveIndex, - children, - numberOfPagesPerScreen, - totalScreensNumber, - totalNumberOfPages, - onPageButtonClick - } = this.props; - const { currentScreenNumber } = this.state; - const offset = (currentScreenNumber - 1) * numberOfPagesPerScreen; - let currentNumberOfScreens = totalNumberOfPages - numberOfPagesPerScreen * currentScreenNumber; - currentNumberOfScreens = numberOfPagesPerScreen < currentNumberOfScreens ? numberOfPagesPerScreen : currentNumberOfScreens; - currentNumberOfScreens = currentNumberOfScreens <= 0 ? numberOfPagesPerScreen : currentNumberOfScreens; +const ReactPagination = props => { + const { + currentActiveIndex, + children, + numberOfPagesPerScreen, + totalNumberOfPages, + onPageButtonClick, + prefix, + suffix, + icons + } = props; + + if (!totalNumberOfPages || currentActiveIndex > totalNumberOfPages) { return React.createElement( 'div', - { className: 'pagination-continer' }, - children, + { className: 'center' }, React.createElement( - 'div', - { className: 'buttons-container' }, - React.createElement( - 'div', - null, - currentScreenNumber !== 1 && React.createElement( - 'button', - { className: 'previous-btn', onClick: () => this.setState({ currentScreenNumber: this.state.currentScreenNumber - 1 }) }, - ' Previous ' - ), - times(currentNumberOfScreens, idx => React.createElement( - 'button', - { - key: idx, - onClick: () => { - onPageButtonClick(idx + 1 + offset); - }, - className: classNames({ active: currentActiveIndex === idx + 1 + offset }) - }, - idx + 1 + offset - )), - currentScreenNumber < totalScreensNumber && React.createElement( - 'button', - { className: 'next-btn', onClick: () => this.setState({ currentScreenNumber: this.state.currentScreenNumber + 1 }) }, - ' Next ' - ) - ) + 'h4', + null, + ' You are in wrong page ' ) ); } -} + + const minPoint = 1; + const midPoint = Math.ceil(numberOfPagesPerScreen / 2); + let buttonsListStartAt = minPoint; + let buttonsListEndsAt = numberOfPagesPerScreen; + const lastScreenPagesMinNumber = totalNumberOfPages - numberOfPagesPerScreen; + const isCurrentNeartoEnd = lastScreenPagesMinNumber < currentActiveIndex < totalNumberOfPages; + const isCurrentAtMiddle = !(currentActiveIndex <= numberOfPagesPerScreen - midPoint) && !(totalNumberOfPages - midPoint < currentActiveIndex); + + if (isCurrentAtMiddle && midPoint !== currentActiveIndex) { + // middle + buttonsListStartAt = currentActiveIndex - midPoint; + buttonsListEndsAt = currentActiveIndex + midPoint; + } else if (isCurrentNeartoEnd && totalNumberOfPages - midPoint < currentActiveIndex) { + // end + buttonsListStartAt = lastScreenPagesMinNumber; + buttonsListEndsAt = totalNumberOfPages; + } + buttonsListStartAt = buttonsListStartAt < minPoint ? minPoint : buttonsListStartAt; + buttonsListEndsAt = buttonsListEndsAt > totalNumberOfPages ? totalNumberOfPages : buttonsListEndsAt; + const ButtonsList = []; + for (let i = buttonsListStartAt; i <= buttonsListEndsAt; i += 1) { + const newButton = React.createElement( + 'button', + { + onClick: () => { + onPageButtonClick(i); + }, + className: classNames({ active: currentActiveIndex === i }) + }, + i + ); + ButtonsList.push(newButton); + } + return React.createElement( + 'div', + { className: 'pagination-continer' }, + children, + React.createElement( + 'div', + { className: 'buttons-container' }, + React.createElement( + 'div', + { activeIndex: currentActiveIndex, pagination: true }, + prefix, + currentActiveIndex > midPoint + 1 && React.createElement( + 'button', + { icon: true, className: 'previous-btn', onClick: () => onPageButtonClick(1) }, + ' ', + icons.leftMost, + ' ' + ), + currentActiveIndex > midPoint + 1 && React.createElement( + 'button', + { icon: true, className: 'previous-btn', onClick: () => onPageButtonClick(currentActiveIndex - 1) }, + ' ', + icons.left, + ' ' + ), + ButtonsList, + !(totalNumberOfPages - midPoint < currentActiveIndex) && React.createElement( + 'button', + { icon: true, className: 'next-btn', onClick: () => onPageButtonClick(currentActiveIndex + 1) }, + ' ', + icons.right, + ' ' + ), + !(totalNumberOfPages - midPoint < currentActiveIndex) && React.createElement( + 'button', + { icon: true, className: 'next-btn', onClick: () => onPageButtonClick(totalNumberOfPages) }, + ' ', + icons.rightMost, + ' ' + ), + suffix + ) + ) + ); +}; +ReactPagination.defaultProps = { + icons: { + left: React.createElement( + 'span', + null, + '\u2190' + ), + leftMost: React.createElement( + 'span', + null, + '\u21C7' + ), + right: React.createElement( + 'span', + null, + '\u2192' + ), + rightMost: React.createElement( + 'span', + null, + '\u21C9' + ) + } +}; export default ReactPagination; \ No newline at end of file diff --git a/package.json b/package.json index 3763220..27ade53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pagination-with-react", - "version": "0.1.2", + "version": "1.0.1", "main": "dist/index.js", "module": "dist/index.js", "files": [ diff --git a/src/index.js b/src/index.js index fef3075..ab0b3d7 100644 --- a/src/index.js +++ b/src/index.js @@ -12,16 +12,10 @@ class App extends React.Component{ } } render() { - const totalItems = 500; - const numberOfItemsPerPage = 10; - const numberOfPagesPerScreen = 10; - const totalNumberOfPages = round(totalItems / numberOfItemsPerPage); - const totalScreensNumber = round(totalNumberOfPages / numberOfPagesPerScreen); return ( { this.setState({ id, diff --git a/src/lib/components/ReactPagination.js b/src/lib/components/ReactPagination.js index 2c06b10..63829ea 100644 --- a/src/lib/components/ReactPagination.js +++ b/src/lib/components/ReactPagination.js @@ -2,64 +2,87 @@ import React from 'react'; import times from 'lodash.times'; import classNames from 'classnames'; -class ReactPagination extends React.Component { - constructor(props) { - super(props); - let currentScreenNumber = 1; - const { totalScreensNumber, numberOfPagesPerScreen, currentActiveIndex } = props; - for (let i = 1; i <= totalScreensNumber; i += 1) { - if ((i * numberOfPagesPerScreen) >= currentActiveIndex) { - currentScreenNumber = i; - break; - } - } - this.state = { - currentScreenNumber, - }; - } - render() { - const { - currentActiveIndex, - children, - numberOfPagesPerScreen, - totalScreensNumber, - totalNumberOfPages, - onPageButtonClick, - } = this.props; - const { currentScreenNumber } = this.state; - const offset = (currentScreenNumber - 1) * numberOfPagesPerScreen; - let currentNumberOfScreens = totalNumberOfPages - (numberOfPagesPerScreen * currentScreenNumber); - currentNumberOfScreens = numberOfPagesPerScreen < currentNumberOfScreens - ? numberOfPagesPerScreen - : currentNumberOfScreens; - currentNumberOfScreens = currentNumberOfScreens <= 0 - ? numberOfPagesPerScreen - : currentNumberOfScreens; +const ReactPagination = (props) =>{ + const { + currentActiveIndex, + children, + numberOfPagesPerScreen, + totalNumberOfPages, + onPageButtonClick, + prefix, + suffix, + icons, + } = props; + + if (!totalNumberOfPages || currentActiveIndex > totalNumberOfPages) { return ( -
- {children} -
-
- { currentScreenNumber !== 1 && } - { - times(currentNumberOfScreens, idx => ( - - )) - } - { currentScreenNumber < totalScreensNumber && } -
-
+
+

You are in wrong page

); } + + const minPoint = 1; + const midPoint = Math.ceil(numberOfPagesPerScreen / 2); + let buttonsListStartAt = minPoint; + let buttonsListEndsAt = numberOfPagesPerScreen; + const lastScreenPagesMinNumber = totalNumberOfPages - numberOfPagesPerScreen; + const isCurrentNeartoEnd = lastScreenPagesMinNumber < currentActiveIndex < totalNumberOfPages; + const isCurrentAtMiddle = + !(currentActiveIndex <= (numberOfPagesPerScreen - midPoint)) && + !((totalNumberOfPages - midPoint) < currentActiveIndex); + + if (isCurrentAtMiddle && midPoint !== currentActiveIndex) { // middle + buttonsListStartAt = currentActiveIndex - midPoint; + buttonsListEndsAt = currentActiveIndex + midPoint; + } else if (isCurrentNeartoEnd && ((totalNumberOfPages - midPoint) < currentActiveIndex)) { // end + buttonsListStartAt = lastScreenPagesMinNumber; + buttonsListEndsAt = totalNumberOfPages; + } + buttonsListStartAt = buttonsListStartAt < minPoint + ? minPoint + : buttonsListStartAt; + buttonsListEndsAt = buttonsListEndsAt > totalNumberOfPages + ? totalNumberOfPages + : buttonsListEndsAt; + const ButtonsList = []; + for (let i = buttonsListStartAt; i <= buttonsListEndsAt; i += 1) { + const newButton = ( + + ); + ButtonsList.push(newButton); + } + return ( +
+ {children} +
+
+ {prefix} + { currentActiveIndex > (midPoint + 1) && } + { currentActiveIndex > (midPoint + 1) && } + {ButtonsList} + { !((totalNumberOfPages - midPoint) < currentActiveIndex) && } + { !((totalNumberOfPages - midPoint) < currentActiveIndex) && } + {suffix} +
+
+
+ ); +} +ReactPagination.defaultProps = { + icons: { + left: , + leftMost: , + right: , + rightMost: , + } } export default ReactPagination;