Created
February 26, 2018 16:56
-
-
Save schester44/441f1fd0ee035885de1ca2cec2f980ff to your computer and use it in GitHub Desktop.
React-based Pagination component & HOC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Example Usage: | |
import React from "react" | |
import Pagination, { withPagination } from "components/Pagination" | |
const DeviceList = ({ data, setCurrentPage, currentPage }) => { | |
const perPage = 25 | |
const lastIndex = currentPage * perPage | |
const firstIndex = lastIndex - perPage | |
const currentDevices = data.slice(firstIndex, lastIndex) | |
return ( | |
<div> | |
<Wrapper>{currentDevices.map((product, key) => <DeviceListItem key={key} data={product} />)}</Wrapper> | |
<Pagination | |
totalItems={data.length} | |
perPage={perPage} | |
currentPage={currentPage} | |
setCurrentPage={setCurrentPage} | |
/> | |
</div> | |
) | |
} | |
export default withPagination(DeviceList) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react" | |
import styled, { withTheme } from "styled-components" | |
const Wrapper = styled.ul` | |
position: relative; | |
list-style-type: none; | |
margin: 50px auto 10px auto; | |
` | |
const Page = styled.li` | |
display: inline; | |
padding: 5px 10px; | |
background: white; | |
cursor: pointer; | |
border-radius: 3px; | |
margin-left: 5px; | |
user-select: none; | |
${props => | |
props.active && | |
` | |
cursor: default; | |
background: ${props.theme.layout.primaryThemeColor}; | |
color: white; | |
`}; | |
` | |
const Pagination = ({ currentPage, totalItems, perPage, setCurrentPage }) => { | |
const handleClick = event => { | |
setCurrentPage(parseInt(event.target.id, 10)) | |
} | |
const pageNumbers = [] | |
for (let i = 1; i <= Math.ceil(totalItems / perPage); i++) { | |
pageNumbers.push(i) | |
} | |
const displayNumbers = pageNumbers.slice(currentPage - 5 > 0 ? currentPage - 5 : 0, currentPage + 5) | |
return <div> | |
{pageNumbers.length > 1 ? <Wrapper> | |
{currentPage > 5 && <Page id={1} onClick={handleClick}> | |
First | |
</Page>} | |
{displayNumbers.map(number => ( | |
<Page active={currentPage === number} key={number} id={number} onClick={handleClick}> | |
{number} | |
</Page> | |
))} | |
{currentPage !== pageNumbers.length && pageNumbers.length > 5 && <Page id={pageNumbers.length} onClick={handleClick}> | |
Last | |
</Page>} | |
</Wrapper> : null} | |
</div> | |
} | |
const withPagination = (WrappedComponent) => { | |
return class extends Component { | |
constructor(props) { | |
super(props) | |
this.setCurrentPage = this.setCurrentPage.bind(this) | |
this.state = { | |
currentPage: 1 | |
} | |
} | |
setCurrentPage(currentPage) { | |
this.setState({ currentPage }) | |
} | |
render() { | |
return ( | |
<WrappedComponent setCurrentPage={this.setCurrentPage} currentPage={this.state.currentPage} {...this.props} /> | |
) | |
} | |
} | |
} | |
export {withPagination} | |
export default withTheme(Pagination) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment