Advertisement
Guest User

Untitled

a guest
Dec 17th, 2017
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.92 KB | None | 0 0
  1. import React from 'react';
  2.  
  3. const FIRST_PAGE = 1
  4.  
  5. export const Paginator = ({ current, total, range }) => {
  6. // range should be odd for a nice look, so prepare it
  7. const isRangeSimmetrical = !(range%2 === 0)
  8. const simmetricalRange = isRangeSimmetrical ? range : (range + 1)
  9. const halfRange = (simmetricalRange - 1) / 2
  10.  
  11. return (
  12. <div>
  13. { renderLeftArrow(current) }
  14. { renderFirstPage(current, total, halfRange) }
  15. { renderLeftDivider(current, total, halfRange) }
  16.  
  17. { renderLeftRange(current, total, halfRange) }
  18.  
  19. { renderCurrentPage(current) }
  20.  
  21. { renderRightRange(current, total, halfRange) }
  22.  
  23. { renderRightDivider(current, total, halfRange) }
  24. { renderLastPage(current, total, halfRange) }
  25. { renderRightArrow(current, total) }
  26. </div>
  27. )
  28. }
  29.  
  30.  
  31. // logical render functions
  32.  
  33. const renderLeftArrow = current => {
  34. const isVisible = current > FIRST_PAGE
  35.  
  36. return (isVisible ? <LeftArrow /> : '' )
  37. }
  38.  
  39. const renderRightArrow = (current, total) => {
  40. const isVisible = current < total
  41.  
  42. return (isVisible ? <RightArrow /> : '')
  43. }
  44.  
  45. const renderLeftDivider = (current, total, halfRange) => {
  46. const isAdditionalPart = (current + halfRange - total) > 0
  47. const additionalPart = isAdditionalPart ? (current + halfRange - total) : 0
  48. const leftRange = halfRange + additionalPart
  49.  
  50. const isVisible = (current - leftRange) > (FIRST_PAGE + 1)
  51.  
  52. return isVisible && <Divider />
  53. }
  54.  
  55. const renderRightDivider = (current, total, halfRange) => {
  56. const isAdditionalPart = (current - halfRange) < 1
  57. const additionalPart = isAdditionalPart ? -(current - 1 - halfRange) : 0
  58. const rightRange = halfRange + additionalPart
  59.  
  60. const isLastNextToRange = (current + rightRange + 1) >= total
  61. const isVisible = !isLastNextToRange
  62.  
  63. return (isVisible && <Divider />)
  64. }
  65.  
  66. const renderFirstPage = (current, total, halfRange) => {
  67. const isAdditionalPart = (current + halfRange - total) > 0
  68. const additionalPart = isAdditionalPart ? (current + halfRange - total) : 0
  69. const leftRange = halfRange + additionalPart
  70.  
  71. const isVisible = (current - leftRange) > FIRST_PAGE
  72.  
  73. return (isVisible && <PageButton page={1} />)
  74. }
  75.  
  76.  
  77. const renderLastPage = (current, total, halfRange) => {
  78. const isAdditionalPart = (current - halfRange) < 1
  79. const additionalPart = isAdditionalPart ? -(current - 1 - halfRange) : 0
  80. const rightRange = halfRange + additionalPart
  81.  
  82. const isLastInFrameRange = (current + rightRange) >= total
  83. const isCurrentLast = (current === total)
  84. const isVisible = !isCurrentLast && !isLastInFrameRange
  85.  
  86. return (isVisible && <PageButton page={total} />)
  87. }
  88.  
  89.  
  90. const renderPagesFrame = (current, total, halfRange) => {
  91. const lowerLimit = current - halfRange
  92. const upperLimit = current + halfRange
  93.  
  94. const isLowerBelowFirst = lowerLimit < FIRST_PAGE
  95. const isUpperOverTotal = upperLimit > total
  96.  
  97. const frameBeginning = isLowerBelowFirst ? FIRST_PAGE : (current - halfRange)
  98. const frameEnd = isUpperOverTotal ? total : (current + halfRange)
  99.  
  100. const pagesToRender = intsInRange(frameBeginning, frameEnd)
  101.  
  102. return (renderPages(pagesToRender, current))
  103. }
  104.  
  105.  
  106. const renderLeftRange = (current, total, halfRange) => {
  107. const rightLimit = current - 1
  108.  
  109. const isAdditionalPart = (current + halfRange - total) > 0
  110. const additionalPart = isAdditionalPart ? (current + halfRange - total) : 0
  111. const leftRange = halfRange + additionalPart
  112. const isRangeUnderFirstPage = (current - leftRange) < 1
  113.  
  114. const leftLimit = isRangeUnderFirstPage ? 1 : (current - leftRange)
  115.  
  116. const pagesToRender = rightLimit > 0 ? intsInRange(leftLimit, rightLimit) : []
  117.  
  118. return renderPages(pagesToRender, current)
  119. }
  120.  
  121.  
  122. const renderCurrentPage = (current) => (
  123. <PageButton page={current} style={{color: 'red'}}/>
  124. )
  125.  
  126.  
  127. const renderRightRange = (current, total, halfRange) => {
  128. const leftLimit = current + 1
  129.  
  130. const isAdditionalPart = (current - halfRange) < 1
  131. const additionalPart = isAdditionalPart ? -(current - 1 - halfRange) : 0
  132. const rightRange = halfRange + additionalPart
  133. const isRightOverTotal = (current + rightRange) > total
  134.  
  135. const rightLimit = isRightOverTotal ? total : current + rightRange
  136.  
  137. const pagesToRender = rightLimit > total ? [] : intsInRange(leftLimit, rightLimit)
  138.  
  139. return renderPages(pagesToRender, current)
  140. }
  141.  
  142.  
  143.  
  144.  
  145. // visual elements
  146.  
  147. const LeftArrow = () => (
  148. <span> { '<' } </span>
  149. )
  150.  
  151. const RightArrow = () => (
  152. <span> { '>' } </span>
  153. )
  154. const Divider = () => (
  155. <span> ... </span>
  156. )
  157.  
  158. const PageButton = ({ page, style = {} }) => (
  159. <span style={style}>{ page }</span>
  160. )
  161.  
  162. const renderPages = (pages, current) => (
  163. pages.map((page, i) => (
  164. <PageButton page={page} key={i} />
  165. ))
  166. )
  167.  
  168.  
  169.  
  170. // handy function
  171.  
  172. const intsInRange = (lowerBound, upperBound) => {
  173. const range = upperBound - lowerBound + 1
  174. return Array.from(new Array(range), (x, i) => (i + lowerBound))
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement