Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React from 'react';
- const FIRST_PAGE = 1
- export const Paginator = ({ current, total, range }) => {
- // range should be odd for a nice look, so prepare it
- const isRangeSimmetrical = !(range%2 === 0)
- const simmetricalRange = isRangeSimmetrical ? range : (range + 1)
- const halfRange = (simmetricalRange - 1) / 2
- return (
- <div>
- { renderLeftArrow(current) }
- { renderFirstPage(current, total, halfRange) }
- { renderLeftDivider(current, total, halfRange) }
- { renderLeftRange(current, total, halfRange) }
- { renderCurrentPage(current) }
- { renderRightRange(current, total, halfRange) }
- { renderRightDivider(current, total, halfRange) }
- { renderLastPage(current, total, halfRange) }
- { renderRightArrow(current, total) }
- </div>
- )
- }
- // logical render functions
- const renderLeftArrow = current => {
- const isVisible = current > FIRST_PAGE
- return (isVisible ? <LeftArrow /> : '' )
- }
- const renderRightArrow = (current, total) => {
- const isVisible = current < total
- return (isVisible ? <RightArrow /> : '')
- }
- const renderLeftDivider = (current, total, halfRange) => {
- const isAdditionalPart = (current + halfRange - total) > 0
- const additionalPart = isAdditionalPart ? (current + halfRange - total) : 0
- const leftRange = halfRange + additionalPart
- const isVisible = (current - leftRange) > (FIRST_PAGE + 1)
- return isVisible && <Divider />
- }
- const renderRightDivider = (current, total, halfRange) => {
- const isAdditionalPart = (current - halfRange) < 1
- const additionalPart = isAdditionalPart ? -(current - 1 - halfRange) : 0
- const rightRange = halfRange + additionalPart
- const isLastNextToRange = (current + rightRange + 1) >= total
- const isVisible = !isLastNextToRange
- return (isVisible && <Divider />)
- }
- const renderFirstPage = (current, total, halfRange) => {
- const isAdditionalPart = (current + halfRange - total) > 0
- const additionalPart = isAdditionalPart ? (current + halfRange - total) : 0
- const leftRange = halfRange + additionalPart
- const isVisible = (current - leftRange) > FIRST_PAGE
- return (isVisible && <PageButton page={1} />)
- }
- const renderLastPage = (current, total, halfRange) => {
- const isAdditionalPart = (current - halfRange) < 1
- const additionalPart = isAdditionalPart ? -(current - 1 - halfRange) : 0
- const rightRange = halfRange + additionalPart
- const isLastInFrameRange = (current + rightRange) >= total
- const isCurrentLast = (current === total)
- const isVisible = !isCurrentLast && !isLastInFrameRange
- return (isVisible && <PageButton page={total} />)
- }
- const renderPagesFrame = (current, total, halfRange) => {
- const lowerLimit = current - halfRange
- const upperLimit = current + halfRange
- const isLowerBelowFirst = lowerLimit < FIRST_PAGE
- const isUpperOverTotal = upperLimit > total
- const frameBeginning = isLowerBelowFirst ? FIRST_PAGE : (current - halfRange)
- const frameEnd = isUpperOverTotal ? total : (current + halfRange)
- const pagesToRender = intsInRange(frameBeginning, frameEnd)
- return (renderPages(pagesToRender, current))
- }
- const renderLeftRange = (current, total, halfRange) => {
- const rightLimit = current - 1
- const isAdditionalPart = (current + halfRange - total) > 0
- const additionalPart = isAdditionalPart ? (current + halfRange - total) : 0
- const leftRange = halfRange + additionalPart
- const isRangeUnderFirstPage = (current - leftRange) < 1
- const leftLimit = isRangeUnderFirstPage ? 1 : (current - leftRange)
- const pagesToRender = rightLimit > 0 ? intsInRange(leftLimit, rightLimit) : []
- return renderPages(pagesToRender, current)
- }
- const renderCurrentPage = (current) => (
- <PageButton page={current} style={{color: 'red'}}/>
- )
- const renderRightRange = (current, total, halfRange) => {
- const leftLimit = current + 1
- const isAdditionalPart = (current - halfRange) < 1
- const additionalPart = isAdditionalPart ? -(current - 1 - halfRange) : 0
- const rightRange = halfRange + additionalPart
- const isRightOverTotal = (current + rightRange) > total
- const rightLimit = isRightOverTotal ? total : current + rightRange
- const pagesToRender = rightLimit > total ? [] : intsInRange(leftLimit, rightLimit)
- return renderPages(pagesToRender, current)
- }
- // visual elements
- const LeftArrow = () => (
- <span> { '<' } </span>
- )
- const RightArrow = () => (
- <span> { '>' } </span>
- )
- const Divider = () => (
- <span> ... </span>
- )
- const PageButton = ({ page, style = {} }) => (
- <span style={style}>{ page }</span>
- )
- const renderPages = (pages, current) => (
- pages.map((page, i) => (
- <PageButton page={page} key={i} />
- ))
- )
- // handy function
- const intsInRange = (lowerBound, upperBound) => {
- const range = upperBound - lowerBound + 1
- return Array.from(new Array(range), (x, i) => (i + lowerBound))
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement